home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / konamiic.c < prev    next >
Text File  |  2000-04-23  |  132KB  |  4,576 lines

  1. #define VERBOSE 0
  2.  
  3. /***************************************************************************
  4.  
  5. TODO:
  6. - implement shadows properly
  7. - in Aliens shadows should be disabled (tubes at the beginning of the game
  8.   have a vertical line which is supposed to be white)
  9. - understand global Y position for the 053247
  10. - understand how the 051316 positioning works
  11.  
  12.  
  13.                       Emulated
  14.                          |
  15.                   board #|year    CPU      tiles        sprites  priority     other
  16.                     -----|----  ------ ------------- ------------- ------ ----------------
  17. Hyper Crash         GX401 1985
  18. Twinbee             GX412*1985   68000           GX400
  19. Yie Ar Kung Fu      GX407*1985    6809
  20. Gradius / Nemesis   GX456*1985   68000           GX400
  21. Shao-lins Road      GX477*1985    6809
  22. Jail Break          GX507*1986 KONAMI-1          005849
  23. Finalizer           GX523*1985 KONAMI-1          005885
  24. Konami's Ping Pong  GX555*1985     Z80
  25. Iron Horse          GX560*1986    6809           005885
  26. Konami GT           GX561*1985   68000           GX400
  27. Green Beret         GX577*1985     Z80           005849
  28. Galactic Warriors   GX578*1985   68000           GX400
  29. Salamander          GX587*1986   68000           GX400
  30. WEC Le Mans 24      GX602*1986 2x68000
  31. BAW                 GX604 1987
  32. Combat School       GX611*1987    6309           007121(x2)               007327 (palette)
  33. Rock 'n Rage /      GX620*1986    6309 007342        007420               007327 (palette)
  34.   Koi no Hotrock
  35. Mr Kabuki/Mr Goemon GX621*1986     Z80           005849
  36. Jackal              GX631*1986    6809?          005885(x2)
  37. Contra / Gryzor     GX633*1987    6809?          007121(x2)               007593 (palette)
  38. Flak Attack         GX669*1987    6309           007121                   007327 (palette) 007452
  39. Devil World / Dark  GX687*1987 2x68000           TWIN16
  40.   Adventure / Majuu no Oukoku
  41. Double Dribble      GX690*1986  3x6809           005885(x2)               007327 (palette) 007452
  42. Kitten Kaboodle     GX712+1988                   GX400                    007593 (palette) 051550
  43. Chequered Flag      GX717*1988  052001               051960 051937(x2)    051316(x2) (zoom/rotation) 051733 (protection)
  44. Fast Lane           GX752*1987    6309           007121                   051733 (protection) 007801
  45. Hot Chase           GX763*1988 2x68000                                    051316(x3) (zoom/rotation) 007634 007635 007558 007557
  46. Rack 'Em Up /       GX765*1987    6309 007342        007420               007327 (palette) 007324
  47.   The Hustler
  48. Haunted Castle      GX768*1988  052001           007121(x2)               007327 (palette)
  49. Ajax / Typhoon      GX770*1987   6309+ 052109 051962 051960 051937  PROM  051316 (zoom/rotation) 007327 (palette)
  50.                                 052001
  51. Labyrinth Runner    GX771*1987    6309           007121                   007593 (palette) 051733 (protection) 051550
  52. Super Contra        GX775*1988  052001 052109 051962 051960 051937  PROM  007327 (palette)
  53. Battlantis          GX777*1987    6309 007342        007420               007327 (palette) 007324
  54. Vulcan Venture /    GX785*1988 2x68000           TWIN16
  55.   Gradius 2
  56. City Bomber         GX787+1987   68000           GX400                    007593 (palette) 051550
  57. Over Drive          GX789 1990
  58. Hyper Crash         GX790 1987
  59. Blades of Steel     GX797*1987    6309 007342        007420               007327 (palette) 051733 (protection)
  60. The Main Event      GX799*1988    6309 052109 051962 051960 051937  PROM
  61. Missing in Action   GX808*1989   68000 052109 051962 051960 051937  PROM
  62. Missing in Action J GX808*1989 2x68000           TWIN16
  63. Crime Fighters      GX821*1989  052526 052109 051962 051960 051937  PROM
  64. Special Project Y   GX857*1989    6309 052109 051962 051960 051937  PROM  052591 (protection)
  65. '88 Games           GX861*1988  052001 052109 051962 051960 051937  PROM  051316 (zoom/rotation)
  66. Final Round /       GX870*1988 1x68000           TWIN16?
  67.   Hard Puncher
  68. Thunder Cross       GX873*1988  052001 052109 051962 051960 051937  PROM  007327 (palette) 052591 (protection)
  69. Aliens              GX875*1990  052526 052109 051962 051960 051937  PROM
  70. Gang Busters        GX878*1988  052526 052109 051962 051960 051937  PROM
  71. Devastators         GX890*1988    6309 052109 051962 051960 051937  PROM  007324 051733 (protection)
  72. Bottom of the Ninth GX891*1989    6809 052109 051962 051960 051937  PROM  051316 (zoom/rotation)
  73. Cue Brick           GX903*1989 2x68000           TWIN16
  74. Punk Shot           GX907*1990   68000 052109 051962 051960 051937 053251
  75. Ultraman            GX910*1991   68000 ------ ------ 051960 051937  PROM  051316(x3) (zoom/rotation) 051550
  76. Surprise Attack     GX911*1990  053248 052109 051962 053245 053244 053251
  77. Lightning Fighters /GX939*1990   68000 052109 051962 053245 053244 053251
  78.   Trigon
  79. Gradius 3           GX945*1989 2x68000 052109 051962 051960 051937  PROM
  80. Parodius            GX955*1990  053248 052109 051962 053245 053244 053251
  81. TMNT                GX963*1989   68000 052109 051962 051960 051937  PROM
  82. Block Hole          GX973*1989  052526 052109 051962 051960 051937  PROM
  83. Escape Kids         GX975 1991  053248 052109 051962 053247 053246 053251 053252 - same board as Vendetta
  84. Rollergames         GX999*1991  053248 ------ ------ 053245 053244        051316 (zoom/rotation) 053252
  85. Bells & Whistles /  GX060*1991   68000 052109 051962 053245 053244 053251 054000 (collision)
  86.   Detana!! Twin Bee
  87. Golfing Greats      GX061*1991   68000 052109 051962 053245 053244 053251 053936 (3D)
  88. TMNT 2              GX063*1991   68000 052109 051962 053245 053244 053251 053990
  89. Sunset Riders       GX064*1991   68000 052109 051962 053245 053244 053251 054358
  90. X-Men               GX065*1992   68000 052109 051962 053247 053246 053251
  91. XEXEX               GX067*1991   68000 054157 054156 053247 053246 053251 054338 054539
  92. Asterix             GX068+1992   68000 054157 054156 053245 053244 053251 054358
  93. G.I. Joe            GX069+1992   68000 054157 054156 053247 053246 053251 054539
  94. The Simpsons        GX072*1991  053248 052109 051962 053247 053246 053251
  95. Thunder Cross 2     GX073*1991   68000 052109 051962 051960 051937 053251 054000 (collision)
  96. Vendetta /          GX081*1991  053248 052109 051962 053247 053246 053251 054000 (collision)
  97.   Crime Fighters 2
  98. Premier Soccer      GX101 1993   68000 052109 051962 053245 053244 053251 053936 (3D)
  99. Hexion              GX122+1992     Z80                                    052591 (protection) 053252
  100. Entapous /          GX123+1993   68000 054157 054156 055673 053246        053252 054000 055555
  101.   Gaiapolis
  102. Mystic Warrior      GX128 1993
  103. Cowboys of Moo Mesa GX151 1993   68000 054157 054156 053247 053246        053252 054338 053990
  104. Violent Storm       GX168+1993   68000 054157 054156 055673 053246        054338 054539(x2) 055550 055555
  105. Bucky 'O Hare       GX173+1992   68000 054157 054156 053247 053246 053251 054338 054539
  106. Potrio              GX174 1992
  107. Lethal Enforcers    GX191 1992    6309 054157(x2) 054156 053245 053244(x2)    054000 054539 054906
  108. Metamorphic Force   GX224 1993
  109. Martial Champion    GX234+1993   68000 054157 054156 055673 053246        053252 054338 054539 055555 053990 054986 054573
  110. Run and Gun         GX247+1993   68000               055673 053246        053253(x2)
  111. Polygonet CommandersGX305 1993   68020                                    056230?063936?054539?054986?
  112.  
  113.  
  114. Notes:
  115. the 051961 is an earlier version of the 052109, functionally equivalent
  116.  
  117.  
  118.  
  119. Status of the ROM tests in the emulated games:
  120.  
  121. Ajax / Typhoon      pass
  122. Super Contra        pass
  123. The Main Event      pass
  124. Missing in Action   pass
  125. Crime Fighters      pass
  126. Special Project Y   pass
  127. Konami 88           pass
  128. Thunder Cross       pass
  129. Aliens              pass
  130. Gang Busters        pass
  131. Devastators         pass
  132. Bottom of the Ninth pass
  133. Punk Shot           pass
  134. Surprise Attack     fails D05-6 (052109) because it uses mirror addresses to
  135.                     select banks, and supporting those addresses breaks the
  136.                     normal game ;-(
  137. Lightning Fighters  pass
  138. Gradius 3           pass
  139. Parodius            pass
  140. TMNT                pass
  141. Block Hole          pass
  142. Rollergames         pass
  143. Bells & Whistles    pass
  144. Golfing Greats      fails B05..B10 (053936)
  145. TMNT 2              pass
  146. Sunset Riders       pass
  147. X-Men               fails 1F (054544)
  148. The Simpsons        pass
  149. Thunder Cross 2     pass
  150. Vendetta            pass
  151. Xexex               pass
  152.  
  153.  
  154. THE FOLLOWING INFORMATION IS PRELIMINARY AND INACCURATE. DON'T RELY ON IT.
  155.  
  156.  
  157. 007121
  158. ------
  159. This is an interesting beast. Many games use two of these in pair.
  160. It manages sprites and two 32x32 tilemaps. The tilemaps can be joined to form
  161. a single 64x32 one, or one of them can be moved to the side of screen, giving
  162. a high score display suitable for vertical games.
  163. The chip also generates clock and interrupt signals suitable for a 6809.
  164. It uses 0x2000 bytes of RAM for the tilemaps and sprites, and an additional
  165. 0x100 bytes, maybe for scroll RAM and line buffers. The maximum addressable
  166. ROM is 0x80000 bytes (addressed 16 bits at a time).
  167. Two 256x4 lookup PROMs are also used to increase the color combinations.
  168. All tilemap / sprite priority handling is done internally and the chip exports
  169. 7 bits of color code, composed of 2 bits of palette bank, 1 bit indicating tile
  170. or sprite, and 4 bits of ROM data remapped through the PROM.
  171.  
  172. inputs:
  173. - address lines (A0-A13)
  174. - data lines (DB0-DB7)
  175. - misc interface stuff
  176. - data from the gfx ROMs (RDL0-RDL7, RDU0-RDU7)
  177. - data from the tile lookup PROMs (VCD0-VCD3)
  178. - data from the sprite lookup PROMs (OCD0-OCD3)
  179.  
  180. outputs:
  181. - address lines for tilemap RAM (AX0-AX12)
  182. - data lines for tilemap RAM (VO0-VO7)
  183. - address lines for the small RAM (FA0-FA7)
  184. - data lines for the small RAM (FD0-FD7)
  185. - address lines for the gfx ROMs (R0-R17)
  186. - address lines for the tile lookup PROMs (VCF0-VCF3, VCB0-VCB3)
  187. - address lines for the sprite lookup PROMs (OCB0-OCB3, OCF0-OCF3)
  188. - NNMI, NIRQ, NFIR, NE, NQ for the main CPU
  189. - misc interface stuff
  190. - color code to be output on screen (COA0-COA6)
  191.  
  192.  
  193. control registers
  194. 000:          scroll x (low 8 bits)
  195. 001: -------x scroll x (high bit)
  196.      ------x- enable rowscroll? (combasc)
  197.      ----x--- this probably selects an alternate screen layout used in combat
  198.               school where tilemap #2 is overlayed on front and doesn't scroll.
  199.               The 32 lines of the front layer can be individually turned on or
  200.               off using the second 32 bytes of scroll RAM.
  201. 002:          scroll y
  202. 003: -------x bit 13 of the tile code
  203.      ------x- unknown (contra)
  204.      -----x-- might be sprite / tilemap priority (0 = sprites have priority)
  205.               (combat school, contra, haunted castle(0/1), labyrunr)
  206.      ----x--- selects sprite buffer (and makes a copy to a private buffer?)
  207.      ---x---- screen layout selector:
  208.               when this is set, 5 columns are added on the left of the screen
  209.               (that means 5 rows at the top for vertical games), and the
  210.               rightmost 2 columns are chopped away.
  211.               Tilemap #2 is used to display the 5 additional columns on the
  212.               left. The rest of tilemap #2 is not used and can be used as work
  213.               RAM by the program.
  214.               The visible area becomes 280x224.
  215.               Note that labyrunr changes this at runtime, setting it during
  216.               gameplay and resetting it on the title screen and crosshatch.
  217.      --x----- might be sprite / tilemap priority (0 = sprites have priority)
  218.               (combat school, contra, haunted castle(0/1), labyrunr)
  219.      -x------ Chops away the leftmost and rightmost columns, switching the
  220.               visible area from 256 to 240 pixels. This is used by combasc on
  221.               the scrolling stages, and by labyrunr on the title screen.
  222.               At first I thought that this enabled an extra bank of 0x40
  223.               sprites, needed by combasc, but labyrunr proves that this is not
  224.               the case
  225.      x------- unknown (contra)
  226. 004: ----xxxx bits 9-12 of the tile code. Only the bits enabled by the following
  227.               mask are actually used, and replace the ones selected by register
  228.               005.
  229.      xxxx---- mask enabling the above bits
  230. 005: selects where in the attribute byte to pick bits 9-12 of the tile code,
  231.      output to pins R12-R15. The bit of the attribute byte to use is the
  232.      specified bit (0-3) + 3, that is one of bits 3-6. Bit 7 is hardcoded as
  233.      bit 8 of the code. Bits 0-2 are used for the color, however note that
  234.      some games (combat school, flak attack, maybe fast lane) use bit 3 as well,
  235.      and indeed there are 4 lines going to the color lookup PROM, so there has
  236.      to be a way to select this.
  237.      ------xx attribute bit to use for tile code bit  9
  238.      ----xx-- attribute bit to use for tile code bit 10
  239.      --xx---- attribute bit to use for tile code bit 11
  240.      xx------ attribute bit to use for tile code bit 12
  241. 006: ----xxxx select additional effect for bits 3-6 of the tile attribute (the
  242.               same ones indexed by register 005). Note that an attribute bit
  243.               can therefore be used at the same time to be BOTH a tile code bit
  244.               and an additional effect.
  245.      -------x bit 3 of attribute is bit 3 of color (combasc, fastlane, flkatck)
  246.      ------x- bit 4 of attribute is tile flip X (assumption - no game uses this)
  247.      -----x-- bit 5 of attribute is tile flip Y (flkatck)
  248.      ----x--- bit 6 of attribute is tile priority over sprites (combasc, hcastle,
  249.               labyrunr)
  250.               Note that hcastle sets this bit for layer 0, and bit 6 of the
  251.               attribute is also used as bit 12 of the tile code, however that
  252.               bit is ALWAYS set thoughout the game.
  253.               combasc uses the bit inthe "graduation" scene during attract mode,
  254.               to place soldiers behind the stand.
  255.               Use in labyrunr has not been investigated yet.
  256.      --xx---- palette bank (both tiles and sprites, see contra)
  257. 007: -------x nmi enable
  258.      ------x- irq enable
  259.      -----x-- firq enable (probably)
  260.      ----x--- flip screen
  261.      ---x---- unknown (contra, labyrunr)
  262.  
  263.  
  264.  
  265. 007342
  266. ------
  267. The 007342 manages 2 64x32 scrolling tilemaps with 8x8 characters, and
  268. optionally generates timing clocks and interrupt signals. It uses 0x2000
  269. bytes of RAM, plus 0x0200 bytes for scrolling, and a variable amount of ROM.
  270. It cannot read the ROMs.
  271.  
  272. control registers
  273. 000: ------x- INT control
  274.      ---x---- flip screen (TODO: doesn't work with thehustl)
  275. 001: Used for banking in Rock'n'Rage
  276. 002: -------x MSB of x scroll 1
  277.      ------x- MSB of x scroll 2
  278.      ---xxx-- layer 1 row/column scroll control
  279.               000 = disabled
  280.               010 = unknown (bladestl shootout between periods)
  281.               011 = 32 columns (Blades of Steel)
  282.               101 = 256 rows (Battlantis, Rock 'n Rage)
  283.      x------- enable sprite wraparound from bottom to top (see Blades of Steel
  284.               high score table)
  285. 003: x scroll 1
  286. 004: y scroll 1
  287. 005: x scroll 2
  288. 006: y scroll 2
  289. 007: not used
  290.  
  291.  
  292. 007420
  293. ------
  294. Sprite generator. 8 bytes per sprite with zoom. It uses 0x200 bytes of RAM,
  295. and a variable amount of ROM. Nothing is known about its external interface.
  296.  
  297.  
  298.  
  299. 052109/051962
  300. -------------
  301. These work in pair.
  302. The 052109 manages 3 64x32 scrolling tilemaps with 8x8 characters, and
  303. optionally generates timing clocks and interrupt signals. It uses 0x4000
  304. bytes of RAM, and a variable amount of ROM. It cannot read the ROMs:
  305. instead, it exports 21 bits (16 from the tilemap RAM + 3 for the character
  306. raster line + 2 additional ones for ROM banking) and these are externally
  307. used to generate the address of the required data on the ROM; the output of
  308. the ROMs is sent to the 051962, along with a color code. In theory you could
  309. have any combination of bits in the tilemap RAM, as long as they add to 16.
  310. In practice, all the games supported so far standardize on the same format
  311. which uses 3 bits for the color code and 13 bits for the character code.
  312. The 051962 multiplexes the data of the three layers and converts it into
  313. palette indexes and transparency bits which will be mixed later in the video
  314. chain.
  315. Priority is handled externally: these chips only generate the tilemaps, they
  316. don't mix them.
  317. Both chips are interfaced with the main CPU. When the RMRD pin is asserted,
  318. the CPU can read the gfx ROM data. This is done by telling the 052109 which
  319. dword to read (this is a combination of some banking registers, and the CPU
  320. address lines), and then reading it from the 051962.
  321.  
  322. 052109 inputs:
  323. - address lines (AB0-AB15, AB13-AB15 seem to have a different function)
  324. - data lines (DB0-DB7)
  325. - misc interface stuff
  326.  
  327. 052109 outputs:
  328. - address lines for the private RAM (RA0-RA12)
  329. - data lines for the private RAM (VD0-VD15)
  330. - NMI, IRQ, FIRQ for the main CPU
  331. - misc interface stuff
  332. - ROM bank selector (CAB1-CAB2)
  333. - character "code" (VC0-VC10)
  334. - character "color" (COL0-COL7); used foc color but also bank switching and tile
  335.   flipping. Exact meaning depends on externl connections. All evidence indicates
  336.   that COL2 and COL3 select the tile bank, and are replaced with the low 2 bits
  337.   from the bank register. The top 2 bits of the register go to CAB1-CAB2.
  338.   However, this DOES NOT WORK with Gradius III. "color" seems to pass through
  339.   unaltered.
  340. - layer A horizontal scroll (ZA1H-ZA4H)
  341. - layer B horizontal scroll (ZB1H-ZB4H)
  342. - ????? (BEN)
  343.  
  344. 051962 inputs:
  345. - gfx data from the ROMs (VC0-VC31)
  346. - color code (COL0-COL7); only COL4-COL7 seem to really be used for color; COL0
  347.   is tile flip X.
  348. - layer A horizontal scroll (ZA1H-ZA4H)
  349. - layer B horizontal scroll (ZB1H-ZB4H)
  350. - let main CPU read the gfx ROMs (RMRD)
  351. - address lines to be used with RMRD (AB0-AB1)
  352. - data lines to be used with RMRD (DB0-DB7)
  353. - ????? (BEN)
  354. - misc interface stuff
  355.  
  356. 051962 outputs:
  357. - FIX layer palette index (DFI0-DFI7)
  358. - FIX layer transparency (NFIC)
  359. - A layer palette index (DSA0-DSAD); DSAA-DSAD seem to be unused
  360. - A layer transparency (NSAC)
  361. - B layer palette index (DSB0-DSBD); DSBA-DSBD seem to be unused
  362. - B layer transparency (NSBC)
  363. - misc interface stuff
  364.  
  365.  
  366. 052109 memory layout:
  367. 0000-07ff: layer FIX tilemap (attributes)
  368. 0800-0fff: layer A tilemap (attributes)
  369. 1000-1fff: layer B tilemap (attributes)
  370. 180c-1833: A y scroll
  371. 1a00-1bff: A x scroll
  372. 1c00     : ?
  373. 1c80     : row/column scroll control
  374.            ------xx layer A row scroll
  375.                     00 = disabled
  376.                     01 = disabled? (gradius3, vendetta)
  377.                     10 = 32 lines
  378.                     11 = 256 lines
  379.            -----x-- layer A column scroll
  380.                     0 = disabled
  381.                     1 = 64 (actually 40) columns
  382.            ---xx--- layer B row scroll
  383.            --x----- layer B column scroll
  384.            surpratk sets this register to 70 during the second boss. There is
  385.            nothing obviously wrong so it's not clear what should happen.
  386. 1d00     : bits 0 & 1 might enable NMI and FIRQ, not sure
  387.          : bit 2 = IRQ enable
  388. 1d80     : ROM bank selector bits 0-3 = bank 0 bits 4-7 = bank 1
  389. 1e00     : ROM subbank selector for ROM testing
  390. 1e80     : bit 0 = flip screen (applies to tilemaps only, not sprites)
  391.          : bit 1 = set by crimfght, mainevt, surpratk, xmen, mia, punkshot, thndrx2, spy
  392.          :         it seems to enable tile flip X, however flip X is handled by the
  393.          :         051962 and it is not hardwired to a specific tile attribute.
  394.          :         Note that xmen, punkshot and thndrx2 set the bit but the current
  395.          :         drivers don't use flip X and seem to work fine.
  396.          : bit 2 = enables tile flip Y when bit 1 of the tile attribute is set
  397. 1f00     : ROM bank selector bits 0-3 = bank 2 bits 4-7 = bank 3
  398. 2000-27ff: layer FIX tilemap (code)
  399. 2800-2fff: layer A tilemap (code)
  400. 3000-37ff: layer B tilemap (code)
  401. 3800-3807: nothing here, so the chip can share address space with a 051937
  402. 380c-3833: B y scroll
  403. 3a00-3bff: B x scroll
  404. 3c00-3fff: nothing here, so the chip can share address space with a 051960
  405. 3d80     : mirror of 1d80, but ONLY during ROM test (surpratk)
  406. 3e00     : mirror of 1e00, but ONLY during ROM test (surpratk)
  407. 3f00     : mirror of 1f00, but ONLY during ROM test (surpratk)
  408. EXTRA ADDRESSING SPACE USED BY X-MEN:
  409. 4000-47ff: layer FIX tilemap (code high bits)
  410. 4800-4fff: layer A tilemap (code high bits)
  411. 5000-57ff: layer B tilemap (code high bits)
  412.  
  413. The main CPU doesn't have direct acces to the RAM used by the 052109, it has
  414. to through the chip.
  415.  
  416.  
  417.  
  418. 051960/051937
  419. -------------
  420. Sprite generators. Designed to work in pair. The 051960 manages the sprite
  421. list and produces and address that is fed to the gfx ROMs. The data from the
  422. ROMs is sent to the 051937, along with color code and other stuff from the
  423. 051960. The 051937 outputs up to 12 bits of palette index, plus "shadow" and
  424. transparency information.
  425. Both chips are interfaced to the main CPU, through 8-bit data buses and 11
  426. bits of address space. The 051937 sits in the range 000-007, while the 051960
  427. in the range 400-7ff (all RAM). The main CPU can read the gfx ROM data though
  428. the 051937 data bus, while the 051960 provides the address lines.
  429. The 051960 is designed to directly address 1MB of ROM space, since it produces
  430. 18 address lines that go to two 16-bit wide ROMs (the 051937 has a 32-bit data
  431. bus to the ROMs). However, the addressing space can be increased by using one
  432. or more of the "color attribute" bits of the sprites as bank selectors.
  433. Moreover a few games store the gfx data in the ROMs in a format different from
  434. the one expected by the 051960, and use external logic to reorder the address
  435. lines.
  436. The 051960 can also genenrate IRQ, FIRQ and NMI signals.
  437.  
  438. memory map:
  439. 000-007 is for the 051937, but also seen by the 051960
  440. 400-7ff is 051960 only
  441. 000     R  bit 0 = unknown, looks like a status flag or something
  442.                    aliens waits for it to be 0 before starting to copy sprite data
  443.                    thndrx2 needs it to pulse for the startup checks to succeed
  444. 000     W  bit 0 = irq enable/acknowledge?
  445.            bit 3 = flip screen (applies to sprites only, not tilemaps)
  446.            bit 4 = unknown, used by Devastators, TMNT, Aliens, Chequered Flag, maybe others
  447.                    aliens sets it just after checking bit 0, and before copying
  448.                    the sprite data
  449.            bit 5 = enable gfx ROM reading
  450. 001     W  Devastators sets bit 1, function unknown, could it be a global shadow enable?
  451.            None of the other games I tested seem to set this register to other than 0.
  452. 002-003 W  selects the portion of the gfx ROMs to be read.
  453. 004     W  Aliens uses this to select the ROM bank to be read, but Punk Shot
  454.            and TMNT don't, they use another bit of the registers above. Many
  455.            other games write to this register before testing.
  456.            It is possible that bits 2-7 of 003 go to OC0-OC5, and bits 0-1 of
  457.            004 go to OC6-OC7.
  458. 004-007 R  reads data from the gfx ROMs (32 bits in total). The address of the
  459.            data is determined by the register above and by the last address
  460.            accessed on the 051960; plus bank switch bits for larger ROMs.
  461.            It seems that the data can also be read directly from the 051960
  462.            address space: 88 Games does this. First it reads 004 and discards
  463.            the result, then it reads from the 051960 the data at the address
  464.            it wants. The normal order is the opposite, read from the 051960 at
  465.            the address you want, discard the result, and fetch the data from
  466.            004-007.
  467. 400-7ff RW sprite RAM, 8 bytes per sprite
  468.  
  469.  
  470.  
  471. 053245/053244
  472. -------------
  473. Sprite generators. The 053245 has a 16-bit data bus to the main CPU.
  474.  
  475. 053244 memory map (but the 053245 sees and processes them too):
  476. 000-001 W  global X offset
  477. 002-003 W  global Y offset
  478. 004     W  unknown
  479. 005     W  bit 0 = flip screen X
  480.            bit 1 = flip screen Y
  481.            bit 2 = unknown, used by Parodius
  482.            bit 4 = enable gfx ROM reading
  483.            bit 5 = unknown, used by Rollergames
  484. 006     W  unknown
  485. 007     W  unknown
  486. 008-009 W  low 16 bits of the ROM address to read
  487. 00a-00b W  high 3 bits of the ROM address to read
  488. 00c-00f R  reads data from the gfx ROMs (32 bits in total). The address of the
  489.            data is determined by the registers above; plus bank switch bits for
  490.            larger ROMs.
  491.  
  492.  
  493.  
  494. 053247/053246
  495. -------------
  496. Sprite generators. Nothing is known about their external interface.
  497. The sprite RAM format is very similar to the 053245.
  498.  
  499. 053246 memory map (but the 053247 sees and processes them too):
  500. 000-001 W  global X offset
  501. 002-003 W  global Y offset. TODO: it is not clear how this works, we use a hack
  502. 004     W  low 8 bits of the ROM address to read
  503. 005     W  bit 0 = flip screen X
  504.            bit 1 = flip screen Y
  505.            bit 2 = unknown
  506.            bit 4 = interrupt enable
  507.            bit 5 = unknown
  508. 006-007 W  high 16 bits of the ROM address to read
  509.  
  510. ???-??? R  reads data from the gfx ROMs (16 bits in total). The address of the
  511.            data is determined by the registers above
  512.  
  513.  
  514.  
  515. 051316
  516. ------
  517. Manages a 32x32 tilemap (16x16 tiles, 512x512 pixels) which can be zoomed,
  518. distorted and rotated.
  519. It uses two internal 24 bit counters which are incremented while scanning the
  520. picture. The coordinates of the pixel in the tilemap that has to be drawn to
  521. the current beam position are the counters / (2^11). Of course if the value is
  522. outside (0..511), nothing is drawn.
  523. The chip doesn't directly generate the color information for the pixel, it
  524. just generates a 24 bit address (whose top 16 bits are the contents of the
  525. tilemap RAM), and a "visible" signal. It's up to external circuitry to convert
  526. the address into a pixel color. Most games seem to use 4bpp graphics, but Ajax
  527. uses 7bpp.
  528.  
  529. control registers
  530. 000-001 X counter starting value / 256
  531. 002-003 amount to add to the X counter after each horizontal pixel
  532. 004-005 amount to add to the X counter after each line (0 = no rotation)
  533. 006-007 Y counter starting value / 256
  534. 008-009 amount to add to the Y counter after each horizontal pixel (0 = no rotation)
  535. 00a-00b amount to add to the Y counter after each line
  536. 00c-00d ROM bank to read, used during ROM testing
  537. 00e     bit 0 = enable ROM reading (active low). This only makes the chip output the
  538.                 requested address: the ROM is actually read externally, not through
  539.                 the chip's data bus.
  540.         bit 1 = unknown
  541.         bit 2 = unknown
  542. 00f     unused
  543.  
  544.  
  545.  
  546. 053251
  547. ------
  548. Priority encoder.
  549.  
  550. The chip has inputs for 5 layers (CI0-CI4); only 4 are used (CI1-CI4)
  551. CI0-CI2 are 9(=5+4) bits inputs, CI3-CI4 8(=4+4) bits
  552.  
  553. The input connctions change from game to game. E.g. in Simpsons,
  554. CI0 = grounded (background color)
  555. CI1 = sprites
  556. CI2 = FIX
  557. CI3 = A
  558. CI4 = B
  559.  
  560. in lgtnfght:
  561. CI0 = grounded
  562. CI1 = sprites
  563. CI2 = FIX
  564. CI3 = B
  565. CI4 = A
  566.  
  567. there are three 6 bit priority inputs, PR0-PR2
  568.  
  569. simpsons:
  570. PR0 = 111111
  571. PR1 = xxxxx0 x bits coming from the sprite attributes
  572. PR2 = 111111
  573.  
  574. lgtnfght:
  575. PR0 = 111111
  576. PR1 = 1xx000 x bits coming from the sprite attributes
  577. PR2 = 111111
  578.  
  579. also two shadow inputs, SDI0 and SDI1 (from the sprite attributes)
  580.  
  581. the chip outputs the 11 bit palette index, CO0-CO10, and two shadow bits.
  582.  
  583. 16 internal registers; registers are 6 bits wide (input is D0-D5)
  584. For the most part, their meaning is unknown
  585. All registers are write only.
  586. There must be a way to enable/disable the three external PR inputs.
  587. Some games initialize the priorities of the sprite & background layers,
  588. others don't. It isn't clear whether these priorities are actually used,
  589. since the external ports are used.
  590.  
  591.  0  priority of CI0 (higher = lower priority)
  592.     punkshot: unused?
  593.     lgtnfght: unused?
  594.     simpsons: 3f = 111111
  595.     xmen:     05 = 000101  default value
  596.     xmen:     09 = 001001  used to swap CI0 and CI2
  597.  1  priority of CI1 (higher = lower priority)
  598.     punkshot: 28 = 101000
  599.     lgtnfght: unused?
  600.     simpsons: unused?
  601.     xmen:     02 = 000010
  602.  2  priority of CI2 (higher = lower priority)
  603.     punkshot: 24 = 100100
  604.     lgtnfght: 24 = 100100
  605.     simpsons: 04 = 000100
  606.     xmen:     09 = 001001  default value
  607.     xmen:     05 = 000101  used to swap CI0 and CI2
  608.  3  priority of CI3 (higher = lower priority)
  609.     punkshot: 34 = 110100
  610.     lgtnfght: 34 = 110100
  611.     simpsons: 28 = 101000
  612.     xmen:     00 = 000000
  613.  4  priority of CI4 (higher = lower priority)
  614.     punkshot: 2c = 101100  default value
  615.     punkshot: 3c = 111100  used to swap CI3 and CI4
  616.     punkshot: 26 = 100110  used to swap CI1 and CI4
  617.     lgtnfght: 2c = 101100
  618.     simpsons: 18 = 011000
  619.     xmen:     fe = 111110
  620.  5  unknown
  621.     punkshot: unused?
  622.     lgtnfght: 2a = 101010
  623.     simpsons: unused?
  624.     xmen: unused?
  625.  6  unknown
  626.     punkshot: 26 = 100110
  627.     lgtnfght: 30 = 110000
  628.     simpsons: 17 = 010111
  629.     xmen:     03 = 000011 (written after initial tests)
  630.  7  unknown
  631.     punkshot: unused?
  632.     lgtnfght: unused?
  633.     simpsons: 27 = 100111
  634.     xmen:     07 = 000111 (written after initial tests)
  635.  8  unknown
  636.     punkshot: unused?
  637.     lgtnfght: unused?
  638.     simpsons: 37 = 110111
  639.     xmen:     ff = 111111 (written after initial tests)
  640.  9  ----xx CI0 palette index base (CO9-CO10)
  641.     --xx-- CI1 palette index base (CO9-CO10)
  642.     xx---- CI2 palette index base (CO9-CO10)
  643. 10  ---xxx CI3 palette index base (CO8-CO10)
  644.     xxx--- CI4 palette index base (CO8-CO10)
  645. 11  unknown
  646.     punkshot: 00 = 000000
  647.     lgtnfght: 00 = 000000
  648.     simpsons: 00 = 000000
  649.     xmen:     00 = 000000 (written after initial tests)
  650. 12  unknown
  651.     punkshot: 04 = 000100
  652.     lgtnfght: 04 = 000100
  653.     simpsons: 05 = 000101
  654.     xmen:     05 = 000101
  655. 13  unused
  656. 14  unused
  657. 15  unused
  658.  
  659.  
  660. 054000
  661. ------
  662. Sort of a protection device, used for collision detection.
  663. It is passed a few parameters, and returns a boolean telling if collision
  664. happened. It has no access to gfx data, it only does arithmetical operations
  665. on the parameters.
  666.  
  667. Memory map:
  668. 00      unused
  669. 01-03 W A center X
  670. 04    W unknown, needed by thndrx2 to pass the startup check, we use a hack
  671. 05      unused
  672. 06    W A semiaxis X
  673. 07    W A semiaxis Y
  674. 08      unused
  675. 09-0b W A center Y
  676. 0c    W unknown, needed by thndrx2 to pass the startup check, we use a hack
  677. 0d      unused
  678. 0e    W B semiaxis X
  679. 0f    W B semiaxis Y
  680. 10      unused
  681. 11-13 W B center Y
  682. 14      unused
  683. 15-17 W B center X
  684. 18    R 0 = collision, 1 = no collision
  685.  
  686. 051733
  687. ------
  688. Sort of a protection device, used for collision detection, and for
  689. arithmetical operations.
  690. It is passed a few parameters, and returns result.
  691.  
  692. Memory map(preliminary):
  693. ------------------------
  694. 00-01 W operand 1
  695. 02-03 W operand 2
  696.  
  697. 00-01 R operand 1/operand 2
  698. 02-03 R operand 1%operand 2?
  699.  
  700. 06-07 W Radius
  701. 08-09 W Y pos of obj1
  702. 0a-0b W X pos of obj1
  703. 0c-0d W Y pos of obj2
  704. 0e-0f W X pos of obj2
  705. 13      W unknown
  706.  
  707. 07      R collision (0x80 = no, 0x00 = yes)
  708.  
  709. Other addresses are unknown or unused.
  710.  
  711. Fast Lane:
  712. ----------
  713. $9def:
  714. This routine is called only after a collision.
  715. (R) 0x0006:    unknown. Only bits 0-3 are used.
  716.  
  717. Blades of Steel:
  718. ----------------
  719. $ac2f:
  720. (R) 0x2f86: unknown. Only uses bit 0.
  721.  
  722. $a5de:
  723. writes to 0x2f84-0x2f85, waits a little, and the read from 0x2f84.
  724.  
  725. $7af3:
  726. (R) 0x2f86: unknown. Only uses bit 0.
  727.  
  728.  
  729. Devastators:
  730. ------------
  731. $6ce8:
  732. reads from 0x0006, and only uses bit 1.
  733.  
  734. ***************************************************************************/
  735.  
  736. #include "driver.h"
  737. #include "vidhrdw/konamiic.h"
  738.  
  739.  
  740. /*
  741.     This recursive function doesn't use additional memory
  742.     (it could be easily converted into an iterative one).
  743.     It's called shuffle because it mimics the shuffling of a deck of cards.
  744. */
  745. static void shuffle(UINT16 *buf,int len)
  746. {
  747.     int i;
  748.     UINT16 t;
  749.  
  750.     if (len == 2) return;
  751.  
  752.     if (len % 4) exit(1);   /* must not happen */
  753.  
  754.     len /= 2;
  755.  
  756.     for (i = 0;i < len/2;i++)
  757.     {
  758.         t = buf[len/2 + i];
  759.         buf[len/2 + i] = buf[len + i];
  760.         buf[len + i] = t;
  761.     }
  762.  
  763.     shuffle(buf,len);
  764.     shuffle(buf + len,len);
  765. }
  766.  
  767.  
  768. /* helper function to join two 16-bit ROMs and form a 32-bit data stream */
  769. void konami_rom_deinterleave_2(int mem_region)
  770. {
  771.     shuffle((UINT16 *)memory_region(mem_region),memory_region_length(mem_region)/2);
  772. }
  773.  
  774. /* helper function to join four 16-bit ROMs and form a 64-bit data stream */
  775. void konami_rom_deinterleave_4(int mem_region)
  776. {
  777.     konami_rom_deinterleave_2(mem_region);
  778.     konami_rom_deinterleave_2(mem_region);
  779. }
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788. /*#define MAX_K007121 2*/
  789.  
  790. /*static*/ unsigned char K007121_ctrlram[MAX_K007121][8];
  791. static int K007121_flipscreen[MAX_K007121];
  792.  
  793.  
  794. void K007121_ctrl_w(int chip,int offset,int data)
  795. {
  796.     switch (offset)
  797.     {
  798.         case 6:
  799. /* palette bank change */
  800. if ((K007121_ctrlram[chip][offset] & 0x30) != (data & 0x30))
  801.     tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
  802.             break;
  803.         case 7:
  804.             K007121_flipscreen[chip] = data & 0x08;
  805.             break;
  806.     }
  807.  
  808.     K007121_ctrlram[chip][offset] = data;
  809. }
  810.  
  811. WRITE_HANDLER( K007121_ctrl_0_w )
  812. {
  813.     K007121_ctrl_w(0,offset,data);
  814. }
  815.  
  816. WRITE_HANDLER( K007121_ctrl_1_w )
  817. {
  818.     K007121_ctrl_w(1,offset,data);
  819. }
  820.  
  821.  
  822. /*
  823.  * Sprite Format
  824.  * ------------------
  825.  *
  826.  * There are 0x40 sprites, each one using 5 bytes. However the number of
  827.  * sprites can be increased to 0x80 with a control register (Combat School
  828.  * sets it on and off during the game).
  829.  *
  830.  * Byte | Bit(s)   | Use
  831.  * -----+-76543210-+----------------
  832.  *   0  | xxxxxxxx | sprite code
  833.  *   1  | xxxx---- | color
  834.  *   1  | ----xx-- | sprite code low 2 bits for 16x8/8x8 sprites
  835.  *   1  | ------xx | sprite code bank bits 1/0
  836.  *   2  | xxxxxxxx | y position
  837.  *   3  | xxxxxxxx | x position (low 8 bits)
  838.  *   4  | xx------ | sprite code bank bits 3/2
  839.  *   4  | --x----- | flip y
  840.  *   4  | ---x---- | flip x
  841.  *   4  | ----xxx- | sprite size 000=16x16 001=16x8 010=8x16 011=8x8 100=32x32
  842.  *   4  | -------x | x position (high bit)
  843.  *
  844.  * Flack Attack uses a different, "wider" layout with 32 bytes per sprites,
  845.  * mapped as follows, and the priority order is reversed. Maybe it is a
  846.  * compatibility mode with an older custom IC. It is not known how this
  847.  * alternate layout is selected.
  848.  *
  849.  * 0 -> e
  850.  * 1 -> f
  851.  * 2 -> 6
  852.  * 3 -> 4
  853.  * 4 -> 8
  854.  *
  855.  */
  856.  
  857. void K007121_sprites_draw(int chip,struct osd_bitmap *bitmap,
  858.         const unsigned char *source,int base_color,int global_x_offset,int bank_base,
  859.         UINT32 pri_mask)
  860. {
  861.     const struct GfxElement *gfx = Machine->gfx[chip];
  862.     int flip_screen = K007121_flipscreen[chip];
  863.     int i,num,inc,offs[5],trans;
  864.     int is_flakatck = K007121_ctrlram[chip][0x06] & 0x04;    /* WRONG!!!! */
  865.  
  866. #if 0
  867. usrintf_showmessage("%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
  868.     K007121_ctrlram[0][0x00],K007121_ctrlram[0][0x01],K007121_ctrlram[0][0x02],K007121_ctrlram[0][0x03],K007121_ctrlram[0][0x04],K007121_ctrlram[0][0x05],K007121_ctrlram[0][0x06],K007121_ctrlram[0][0x07],
  869.     K007121_ctrlram[1][0x00],K007121_ctrlram[1][0x01],K007121_ctrlram[1][0x02],K007121_ctrlram[1][0x03],K007121_ctrlram[1][0x04],K007121_ctrlram[1][0x05],K007121_ctrlram[1][0x06],K007121_ctrlram[1][0x07]);
  870. #endif
  871. #if 0
  872. if (keyboard_pressed(KEYCODE_D))
  873. {
  874.     FILE *fp;
  875.     fp=fopen(chip?"SPRITE1.DMP":"SPRITE0.DMP", "w+b");
  876.     if (fp)
  877.     {
  878.         fwrite(source, 0x800, 1, fp);
  879.         usrintf_showmessage("saved");
  880.         fclose(fp);
  881.     }
  882. }
  883. #endif
  884.  
  885.     if (is_flakatck)
  886.     {
  887.         num = 0x40;
  888.         inc = -0x20;
  889.         source += 0x3f*0x20;
  890.         offs[0] = 0x0e;
  891.         offs[1] = 0x0f;
  892.         offs[2] = 0x06;
  893.         offs[3] = 0x04;
  894.         offs[4] = 0x08;
  895.         /* Flak Attack doesn't use a lookup PROM, it maps the color code directly */
  896.         /* to a palette entry */
  897.         trans = TRANSPARENCY_PEN;
  898.     }
  899.     else    /* all others */
  900.     {
  901.         num = (K007121_ctrlram[chip][0x03] & 0x40) ? 0x80 : 0x40;    /* WRONG!!! (needed by combasc)  */
  902.         inc = 5;
  903.         offs[0] = 0x00;
  904.         offs[1] = 0x01;
  905.         offs[2] = 0x02;
  906.         offs[3] = 0x03;
  907.         offs[4] = 0x04;
  908.         trans = TRANSPARENCY_COLOR;
  909.         /* when using priority buffer, draw front to back */
  910.         if (pri_mask != -1)
  911.         {
  912.             source += (num-1)*inc;
  913.             inc = -inc;
  914.         }
  915.     }
  916.  
  917.     for (i = 0;i < num;i++)
  918.     {
  919.         int number = source[offs[0]];                /* sprite number */
  920.         int sprite_bank = source[offs[1]] & 0x0f;    /* sprite bank */
  921.         int sx = source[offs[3]];                    /* vertical position */
  922.         int sy = source[offs[2]];                    /* horizontal position */
  923.         int attr = source[offs[4]];                /* attributes */
  924.         int xflip = source[offs[4]] & 0x10;        /* flip x */
  925.         int yflip = source[offs[4]] & 0x20;        /* flip y */
  926.         int color = base_color + ((source[offs[1]] & 0xf0) >> 4);
  927.         int width,height;
  928.         static int x_offset[4] = {0x0,0x1,0x4,0x5};
  929.         static int y_offset[4] = {0x0,0x2,0x8,0xa};
  930.         int x,y, ex, ey;
  931.  
  932.         if (attr & 0x01) sx -= 256;
  933.         if (sy >= 240) sy -= 256;
  934.  
  935.         number += ((sprite_bank & 0x3) << 8) + ((attr & 0xc0) << 4);
  936.         number = number << 2;
  937.         number += (sprite_bank >> 2) & 3;
  938.  
  939.         if (!is_flakatck || source[0x00])    /* Flak Attack needs this */
  940.         {
  941.             number += bank_base;
  942.  
  943.             switch( attr&0xe )
  944.             {
  945.                 case 0x06: width = height = 1; break;
  946.                 case 0x04: width = 1; height = 2; number &= (~2); break;
  947.                 case 0x02: width = 2; height = 1; number &= (~1); break;
  948.                 case 0x00: width = height = 2; number &= (~3); break;
  949.                 case 0x08: width = height = 4; number &= (~3); break;
  950.                 default: width = 1; height = 1;
  951. //                    logerror("Unknown sprite size %02x\n",attr&0xe);
  952. //                    usrintf_showmessage("Unknown sprite size %02x\n",attr&0xe);
  953.             }
  954.  
  955.             for (y = 0;y < height;y++)
  956.             {
  957.                 for (x = 0;x < width;x++)
  958.                 {
  959.                     ex = xflip ? (width-1-x) : x;
  960.                     ey = yflip ? (height-1-y) : y;
  961.  
  962.                     if (flip_screen)
  963.                     {
  964.                         if (pri_mask != -1)
  965.                             pdrawgfx(bitmap,gfx,
  966.                                 number + x_offset[ex] + y_offset[ey],
  967.                                 color,
  968.                                 !xflip,!yflip,
  969.                                 248-(sx+x*8),248-(sy+y*8),
  970.                                 &Machine->drv->visible_area,trans,0,
  971.                                 pri_mask);
  972.                         else
  973.                             drawgfx(bitmap,gfx,
  974.                                 number + x_offset[ex] + y_offset[ey],
  975.                                 color,
  976.                                 !xflip,!yflip,
  977.                                 248-(sx+x*8),248-(sy+y*8),
  978.                                 &Machine->drv->visible_area,trans,0);
  979.                     }
  980.                     else
  981.                     {
  982.                         if (pri_mask != -1)
  983.                             pdrawgfx(bitmap,gfx,
  984.                                 number + x_offset[ex] + y_offset[ey],
  985.                                 color,
  986.                                 xflip,yflip,
  987.                                 global_x_offset+sx+x*8,sy+y*8,
  988.                                 &Machine->drv->visible_area,trans,0,
  989.                                 pri_mask);
  990.                         else
  991.                             drawgfx(bitmap,gfx,
  992.                                 number + x_offset[ex] + y_offset[ey],
  993.                                 color,
  994.                                 xflip,yflip,
  995.                                 global_x_offset+sx+x*8,sy+y*8,
  996.                                 &Machine->drv->visible_area,trans,0);
  997.                     }
  998.                 }
  999.             }
  1000.         }
  1001.  
  1002.         source += inc;
  1003.     }
  1004. }
  1005.  
  1006. void K007121_mark_sprites_colors(int chip,
  1007.         const unsigned char *source,int base_color,int bank_base)
  1008. {
  1009.     int i,num,inc,offs[5];
  1010.     int is_flakatck = K007121_ctrlram[chip][0x06] & 0x04;    /* WRONG!!!! */
  1011.  
  1012.     unsigned short palette_map[512];
  1013.  
  1014.     if (is_flakatck)
  1015.     {
  1016.         num = 0x40;
  1017.         inc = -0x20;
  1018.         source += 0x3f*0x20;
  1019.         offs[0] = 0x0e;
  1020.         offs[1] = 0x0f;
  1021.         offs[2] = 0x06;
  1022.         offs[3] = 0x04;
  1023.         offs[4] = 0x08;
  1024.     }
  1025.     else    /* all others */
  1026.     {
  1027.         num = (K007121_ctrlram[chip][0x03] & 0x40) ? 0x80 : 0x40;
  1028.         inc = 5;
  1029.         offs[0] = 0x00;
  1030.         offs[1] = 0x01;
  1031.         offs[2] = 0x02;
  1032.         offs[3] = 0x03;
  1033.         offs[4] = 0x04;
  1034.     }
  1035.  
  1036.     memset (palette_map, 0, sizeof (palette_map));
  1037.  
  1038.     /* sprites */
  1039.     for (i = 0;i < num;i++)
  1040.     {
  1041.         int color;
  1042.  
  1043.         color = base_color + ((source[offs[1]] & 0xf0) >> 4);
  1044.         palette_map[color] |= 0xffff;
  1045.  
  1046.         source += inc;
  1047.     }
  1048.  
  1049.     /* now build the final table */
  1050.     for (i = 0; i < 512; i++)
  1051.     {
  1052.         int usage = palette_map[i], j;
  1053.         if (usage)
  1054.         {
  1055.             for (j = 0; j < 16; j++)
  1056.                 if (usage & (1 << j))
  1057.                     palette_used_colors[i * 16 + j] |= PALETTE_COLOR_VISIBLE;
  1058.         }
  1059.     }
  1060. }
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066.  
  1067.  
  1068. static unsigned char *K007342_ram,*K007342_scroll_ram;
  1069. static int K007342_gfxnum;
  1070. static int K007342_int_enabled;
  1071. static int K007342_flipscreen;
  1072. static int K007342_scrollx[2];
  1073. static int K007342_scrolly[2];
  1074. static unsigned char *K007342_videoram_0,*K007342_colorram_0;
  1075. static unsigned char *K007342_videoram_1,*K007342_colorram_1;
  1076. static int K007342_regs[8];
  1077. static void (*K007342_callback)(int tilemap, int bank, int *code, int *color);
  1078. static struct tilemap *K007342_tilemap[2];
  1079.  
  1080. /***************************************************************************
  1081.  
  1082.   Callbacks for the TileMap code
  1083.  
  1084. ***************************************************************************/
  1085.  
  1086. /*
  1087.   data format:
  1088.   video RAM     xxxxxxxx    tile number (bits 0-7)
  1089.   color RAM     x-------    tiles with priority over the sprites
  1090.   color RAM     -x------    depends on external conections
  1091.   color RAM     --x-----    flip Y
  1092.   color RAM     ---x----    flip X
  1093.   color RAM     ----xxxx    depends on external connections (usually color and banking)
  1094. */
  1095.  
  1096. static unsigned char *colorram,*videoram1,*videoram2;
  1097. static int layer;
  1098.  
  1099. static void tilemap_0_preupdate(void)
  1100. {
  1101.     colorram = K007342_colorram_0;
  1102.     videoram1 = K007342_videoram_0;
  1103.     layer = 0;
  1104. }
  1105.  
  1106. static void tilemap_1_preupdate(void)
  1107. {
  1108.     colorram = K007342_colorram_1;
  1109.     videoram1 = K007342_videoram_1;
  1110.     layer = 1;
  1111. }
  1112.  
  1113. static UINT32 K007342_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
  1114. {
  1115.     /* logical (col,row) -> memory offset */
  1116.     return (col & 0x1f) + ((row & 0x1f) << 5) + ((col & 0x20) << 5);
  1117. }
  1118.  
  1119. static void K007342_get_tile_info(int tile_index)
  1120. {
  1121.     int color, code;
  1122.  
  1123.     color = colorram[tile_index];
  1124.     code = videoram1[tile_index];
  1125.  
  1126.     tile_info.flags = TILE_FLIPYX((color & 0x30) >> 4);
  1127.     tile_info.priority = (color & 0x80) >> 7;
  1128.  
  1129.     (*K007342_callback)(layer, K007342_regs[1], &code, &color);
  1130.  
  1131.     SET_TILE_INFO(K007342_gfxnum,code,color);
  1132. }
  1133.  
  1134. int K007342_vh_start(int gfx_index, void (*callback)(int tilemap, int bank, int *code, int *color))
  1135. {
  1136.     K007342_gfxnum = gfx_index;
  1137.     K007342_callback = callback;
  1138.  
  1139.     K007342_tilemap[0] = tilemap_create(K007342_get_tile_info,K007342_scan,TILEMAP_TRANSPARENT,8,8,64,32);
  1140.     K007342_tilemap[1] = tilemap_create(K007342_get_tile_info,K007342_scan,TILEMAP_TRANSPARENT,8,8,64,32);
  1141.  
  1142.     K007342_ram = malloc(0x2000);
  1143.     K007342_scroll_ram = malloc(0x0200);
  1144.  
  1145.     if (!K007342_ram || !K007342_scroll_ram || !K007342_tilemap[0] || !K007342_tilemap[1])
  1146.     {
  1147.         K007342_vh_stop();
  1148.         return 1;
  1149.     }
  1150.  
  1151.     memset(K007342_ram,0,0x2000);
  1152.  
  1153.     K007342_colorram_0 = &K007342_ram[0x0000];
  1154.     K007342_colorram_1 = &K007342_ram[0x1000];
  1155.     K007342_videoram_0 = &K007342_ram[0x0800];
  1156.     K007342_videoram_1 = &K007342_ram[0x1800];
  1157.  
  1158.     K007342_tilemap[0]->transparent_pen = 0;
  1159.     K007342_tilemap[1]->transparent_pen = 0;
  1160.  
  1161.     return 0;
  1162. }
  1163.  
  1164. void K007342_vh_stop(void)
  1165. {
  1166.     free(K007342_ram);
  1167.     K007342_ram = 0;
  1168.     free(K007342_scroll_ram);
  1169.     K007342_scroll_ram = 0;
  1170. }
  1171.  
  1172. READ_HANDLER( K007342_r )
  1173. {
  1174.     return K007342_ram[offset];
  1175. }
  1176.  
  1177. WRITE_HANDLER( K007342_w )
  1178. {
  1179.     if (offset < 0x1000)
  1180.     {        /* layer 0 */
  1181.         if (K007342_ram[offset] != data)
  1182.         {
  1183.             K007342_ram[offset] = data;
  1184.             tilemap_mark_tile_dirty(K007342_tilemap[0],offset & 0x7ff);
  1185.         }
  1186.     }
  1187.     else
  1188.     {                        /* layer 1 */
  1189.         if (K007342_ram[offset] != data)
  1190.         {
  1191.             K007342_ram[offset] = data;
  1192.             tilemap_mark_tile_dirty(K007342_tilemap[1],offset & 0x7ff);
  1193.         }
  1194.     }
  1195. }
  1196.  
  1197. READ_HANDLER( K007342_scroll_r )
  1198. {
  1199.     return K007342_scroll_ram[offset];
  1200. }
  1201.  
  1202. WRITE_HANDLER( K007342_scroll_w )
  1203. {
  1204.     K007342_scroll_ram[offset] = data;
  1205. }
  1206.  
  1207. WRITE_HANDLER( K007342_vreg_w )
  1208. {
  1209.     switch(offset)
  1210.     {
  1211.         case 0x00:
  1212.             /* bit 1: INT control */
  1213.             K007342_int_enabled = data & 0x02;
  1214.             K007342_flipscreen = data & 0x10;
  1215.             tilemap_set_flip(K007342_tilemap[0],K007342_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
  1216.             tilemap_set_flip(K007342_tilemap[1],K007342_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
  1217.             break;
  1218.         case 0x01:  /* used for banking in Rock'n'Rage */
  1219.             if (data != K007342_regs[1])
  1220.                 tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
  1221.         case 0x02:
  1222.             K007342_scrollx[0] = (K007342_scrollx[0] & 0xff) | ((data & 0x01) << 8);
  1223.             K007342_scrollx[1] = (K007342_scrollx[1] & 0xff) | ((data & 0x02) << 7);
  1224.             break;
  1225.         case 0x03:  /* scroll x (register 0) */
  1226.             K007342_scrollx[0] = (K007342_scrollx[0] & 0x100) | data;
  1227.             break;
  1228.         case 0x04:  /* scroll y (register 0) */
  1229.             K007342_scrolly[0] = data;
  1230.             break;
  1231.         case 0x05:  /* scroll x (register 1) */
  1232.             K007342_scrollx[1] = (K007342_scrollx[1] & 0x100) | data;
  1233.             break;
  1234.         case 0x06:  /* scroll y (register 1) */
  1235.             K007342_scrolly[1] = data;
  1236.         case 0x07:  /* unused */
  1237.             break;
  1238.     }
  1239.     K007342_regs[offset] = data;
  1240. }
  1241.  
  1242. void K007342_tilemap_update(void)
  1243. {
  1244.     int offs;
  1245.  
  1246.  
  1247.     /* update scroll */
  1248.     switch (K007342_regs[2] & 0x1c)
  1249.     {
  1250.         case 0x00:
  1251.         case 0x08:    /* unknown, blades of steel shootout between periods */
  1252.             tilemap_set_scroll_rows(K007342_tilemap[0],1);
  1253.             tilemap_set_scroll_cols(K007342_tilemap[0],1);
  1254.             tilemap_set_scrollx(K007342_tilemap[0],0,K007342_scrollx[0]);
  1255.             tilemap_set_scrolly(K007342_tilemap[0],0,K007342_scrolly[0]);
  1256.             break;
  1257.  
  1258.         case 0x0c:    /* 32 columns */
  1259.             tilemap_set_scroll_rows(K007342_tilemap[0],1);
  1260.             tilemap_set_scroll_cols(K007342_tilemap[0],512);
  1261.             tilemap_set_scrollx(K007342_tilemap[0],0,K007342_scrollx[0]);
  1262.             for (offs = 0;offs < 256;offs++)
  1263.                 tilemap_set_scrolly(K007342_tilemap[0],(offs + K007342_scrollx[0]) & 0x1ff,
  1264.                         K007342_scroll_ram[2*(offs/8)] + 256 * K007342_scroll_ram[2*(offs/8)+1]);
  1265.             break;
  1266.  
  1267.         case 0x14:    /* 256 rows */
  1268.             tilemap_set_scroll_rows(K007342_tilemap[0],256);
  1269.             tilemap_set_scroll_cols(K007342_tilemap[0],1);
  1270.             tilemap_set_scrolly(K007342_tilemap[0],0,K007342_scrolly[0]);
  1271.             for (offs = 0;offs < 256;offs++)
  1272.                 tilemap_set_scrollx(K007342_tilemap[0],(offs + K007342_scrolly[0]) & 0xff,
  1273.                         K007342_scroll_ram[2*offs] + 256 * K007342_scroll_ram[2*offs+1]);
  1274.             break;
  1275.  
  1276.         default:
  1277. usrintf_showmessage("unknown scroll ctrl %02x",K007342_regs[2] & 0x1c);
  1278.             break;
  1279.     }
  1280.  
  1281.     tilemap_set_scrollx(K007342_tilemap[1],0,K007342_scrollx[1]);
  1282.     tilemap_set_scrolly(K007342_tilemap[1],0,K007342_scrolly[1]);
  1283.  
  1284.     /* update all layers */
  1285.     tilemap_0_preupdate(); tilemap_update(K007342_tilemap[0]);
  1286.     tilemap_1_preupdate(); tilemap_update(K007342_tilemap[1]);
  1287.  
  1288. #if 0
  1289.     {
  1290.         static int current_layer = 0;
  1291.  
  1292.         if (keyboard_pressed_memory(KEYCODE_Z)) current_layer = !current_layer;
  1293.         tilemap_set_enable(K007342_tilemap[current_layer], 1);
  1294.         tilemap_set_enable(K007342_tilemap[!current_layer], 0);
  1295.  
  1296.         usrintf_showmessage("regs:%02x %02x %02x %02x-%02x %02x %02x %02x:%02x",
  1297.             K007342_regs[0], K007342_regs[1], K007342_regs[2], K007342_regs[3],
  1298.             K007342_regs[4], K007342_regs[5], K007342_regs[6], K007342_regs[7],
  1299.             current_layer);
  1300.     }
  1301. #endif
  1302. }
  1303.  
  1304. void K007342_tilemap_set_enable(int tilemap, int enable)
  1305. {
  1306.     tilemap_set_enable(K007342_tilemap[tilemap], enable);
  1307. }
  1308.  
  1309. void K007342_tilemap_draw(struct osd_bitmap *bitmap,int num,int flags)
  1310. {
  1311.     tilemap_draw(bitmap,K007342_tilemap[num],flags);
  1312. }
  1313.  
  1314. int K007342_is_INT_enabled(void)
  1315. {
  1316.     return K007342_int_enabled;
  1317. }
  1318.  
  1319.  
  1320.  
  1321. static struct GfxElement *K007420_gfx;
  1322. static void (*K007420_callback)(int *code,int *color);
  1323. static unsigned char *K007420_ram;
  1324.  
  1325. int K007420_vh_start(int gfxnum, void (*callback)(int *code,int *color))
  1326. {
  1327.     K007420_gfx = Machine->gfx[gfxnum];
  1328.     K007420_callback = callback;
  1329.     K007420_ram = malloc(0x200);
  1330.     if (!K007420_ram) return 1;
  1331.  
  1332.     memset(K007420_ram,0,0x200);
  1333.  
  1334.     return 0;
  1335. }
  1336.  
  1337. void K007420_vh_stop(void)
  1338. {
  1339.     free(K007420_ram);
  1340.     K007420_ram = 0;
  1341. }
  1342.  
  1343. READ_HANDLER( K007420_r )
  1344. {
  1345.     return K007420_ram[offset];
  1346. }
  1347.  
  1348. WRITE_HANDLER( K007420_w )
  1349. {
  1350.     K007420_ram[offset] = data;
  1351. }
  1352.  
  1353. /*
  1354.  * Sprite Format
  1355.  * ------------------
  1356.  *
  1357.  * Byte | Bit(s)   | Use
  1358.  * -----+-76543210-+----------------
  1359.  *   0  | xxxxxxxx | y position
  1360.  *   1  | xxxxxxxx | sprite code (low 8 bits)
  1361.  *   2  | xxxxxxxx | depends on external conections. Usually banking
  1362.  *   3  | xxxxxxxx | x position (low 8 bits)
  1363.  *   4  | x------- | x position (high bit)
  1364.  *   4  | -xxx---- | sprite size 000=16x16 001=8x16 010=16x8 011=8x8 100=32x32
  1365.  *   4  | ----x--- | flip y
  1366.  *   4  | -----x-- | flip x
  1367.  *   4  | ------xx | zoom (bits 8 & 9)
  1368.  *   5  | xxxxxxxx | zoom (low 8 bits)  0x080 = normal, < 0x80 enlarge, > 0x80 reduce
  1369.  *   6  | xxxxxxxx | unused
  1370.  *   7  | xxxxxxxx | unused
  1371.  */
  1372.  
  1373. void K007420_sprites_draw(struct osd_bitmap *bitmap)
  1374. {
  1375. #define K007420_SPRITERAM_SIZE 0x200
  1376.     int offs;
  1377.  
  1378.     for (offs = K007420_SPRITERAM_SIZE - 8; offs >= 0; offs -= 8)
  1379.     {
  1380.         int ox,oy,code,color,flipx,flipy,zoom,w,h,x,y;
  1381.         static int xoffset[4] = { 0, 1, 4, 5 };
  1382.         static int yoffset[4] = { 0, 2, 8, 10 };
  1383.  
  1384.         code = K007420_ram[offs+1];
  1385.         color = K007420_ram[offs+2];
  1386.         ox = K007420_ram[offs+3] - ((K007420_ram[offs+4] & 0x80) << 1);
  1387.         oy = 256 - K007420_ram[offs+0];
  1388.         flipx = K007420_ram[offs+4] & 0x04;
  1389.         flipy = K007420_ram[offs+4] & 0x08;
  1390.  
  1391.         (*K007420_callback)(&code,&color);
  1392.  
  1393.         /* kludge for rock'n'rage */
  1394.         if ((K007420_ram[offs+4] == 0x40) && (K007420_ram[offs+1] == 0xff) &&
  1395.             (K007420_ram[offs+2] == 0x00) && (K007420_ram[offs+5] == 0xf0)) continue;
  1396.  
  1397.         /* 0x080 = normal scale, 0x040 = double size, 0x100 half size */
  1398.         zoom = K007420_ram[offs+5] | ((K007420_ram[offs+4] & 0x03) << 8);
  1399.         if (!zoom) continue;
  1400.         zoom = 0x10000 * 128 / zoom;
  1401.  
  1402.         switch (K007420_ram[offs+4] & 0x70)
  1403.         {
  1404.             case 0x30: w = h = 1; break;
  1405.             case 0x20: w = 2; h = 1; code &= (~1); break;
  1406.             case 0x10: w = 1; h = 2; code &= (~2); break;
  1407.             case 0x00: w = h = 2; code &= (~3); break;
  1408.             case 0x40: w = h = 4; code &= (~3); break;
  1409.             default: w = 1; h = 1;
  1410. //logerror("Unknown sprite size %02x\n",(K007420_ram[offs+4] & 0x70)>>4);
  1411.         }
  1412.  
  1413.         if (K007342_flipscreen)
  1414.         {
  1415.             ox = 256 - ox - ((zoom * w + (1<<12)) >> 13);
  1416.             oy = 256 - oy - ((zoom * h + (1<<12)) >> 13);
  1417.             flipx = !flipx;
  1418.             flipy = !flipy;
  1419.         }
  1420.  
  1421.         if (zoom == 0x10000)
  1422.         {
  1423.             int sx,sy;
  1424.  
  1425.             for (y = 0;y < h;y++)
  1426.             {
  1427.                 sy = oy + 8 * y;
  1428.  
  1429.                 for (x = 0;x < w;x++)
  1430.                 {
  1431.                     int c = code;
  1432.  
  1433.                     sx = ox + 8 * x;
  1434.                     if (flipx) c += xoffset[(w-1-x)];
  1435.                     else c += xoffset[x];
  1436.                     if (flipy) c += yoffset[(h-1-y)];
  1437.                     else c += yoffset[y];
  1438.  
  1439.                     drawgfx(bitmap,K007420_gfx,
  1440.                         c,
  1441.                         color,
  1442.                         flipx,flipy,
  1443.                         sx,sy,
  1444.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  1445.  
  1446.                     if (K007342_regs[2] & 0x80)
  1447.                         drawgfx(bitmap,K007420_gfx,
  1448.                             c,
  1449.                             color,
  1450.                             flipx,flipy,
  1451.                             sx,sy-256,
  1452.                             &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  1453.                 }
  1454.             }
  1455.         }
  1456.         else
  1457.         {
  1458.             int sx,sy,zw,zh;
  1459.             for (y = 0;y < h;y++)
  1460.             {
  1461.                 sy = oy + ((zoom * y + (1<<12)) >> 13);
  1462.                 zh = (oy + ((zoom * (y+1) + (1<<12)) >> 13)) - sy;
  1463.  
  1464.                 for (x = 0;x < w;x++)
  1465.                 {
  1466.                     int c = code;
  1467.  
  1468.                     sx = ox + ((zoom * x + (1<<12)) >> 13);
  1469.                     zw = (ox + ((zoom * (x+1) + (1<<12)) >> 13)) - sx;
  1470.                     if (flipx) c += xoffset[(w-1-x)];
  1471.                     else c += xoffset[x];
  1472.                     if (flipy) c += yoffset[(h-1-y)];
  1473.                     else c += yoffset[y];
  1474.  
  1475.                     drawgfxzoom(bitmap,K007420_gfx,
  1476.                         c,
  1477.                         color,
  1478.                         flipx,flipy,
  1479.                         sx,sy,
  1480.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0,
  1481.                         (zw << 16) / 8,(zh << 16) / 8);
  1482.  
  1483.                     if (K007342_regs[2] & 0x80)
  1484.                         drawgfxzoom(bitmap,K007420_gfx,
  1485.                             c,
  1486.                             color,
  1487.                             flipx,flipy,
  1488.                             sx,sy-256,
  1489.                             &Machine->drv->visible_area,TRANSPARENCY_PEN,0,
  1490.                             (zw << 16) / 8,(zh << 16) / 8);
  1491.                 }
  1492.             }
  1493.         }
  1494.     }
  1495. #if 0
  1496.     {
  1497.         static int current_sprite = 0;
  1498.  
  1499.         if (keyboard_pressed_memory(KEYCODE_Z)) current_sprite = (current_sprite+1) & ((K007420_SPRITERAM_SIZE/8)-1);
  1500.         if (keyboard_pressed_memory(KEYCODE_X)) current_sprite = (current_sprite-1) & ((K007420_SPRITERAM_SIZE/8)-1);
  1501.  
  1502.         usrintf_showmessage("%02x:%02x %02x %02x %02x %02x %02x %02x %02x", current_sprite,
  1503.             K007420_ram[(current_sprite*8)+0], K007420_ram[(current_sprite*8)+1],
  1504.             K007420_ram[(current_sprite*8)+2], K007420_ram[(current_sprite*8)+3],
  1505.             K007420_ram[(current_sprite*8)+4], K007420_ram[(current_sprite*8)+5],
  1506.             K007420_ram[(current_sprite*8)+6], K007420_ram[(current_sprite*8)+7]);
  1507.     }
  1508. #endif
  1509. }
  1510.  
  1511.  
  1512.  
  1513.  
  1514. static int K052109_memory_region;
  1515. static int K052109_gfxnum;
  1516. static void (*K052109_callback)(int tilemap,int bank,int *code,int *color);
  1517. static unsigned char *K052109_ram;
  1518. static unsigned char *K052109_videoram_F,*K052109_videoram2_F,*K052109_colorram_F;
  1519. static unsigned char *K052109_videoram_A,*K052109_videoram2_A,*K052109_colorram_A;
  1520. static unsigned char *K052109_videoram_B,*K052109_videoram2_B,*K052109_colorram_B;
  1521. static unsigned char K052109_charrombank[4];
  1522. static int has_extra_video_ram;
  1523. static int K052109_RMRD_line;
  1524. static int K052109_tileflip_enable;
  1525. static int K052109_irq_enabled;
  1526. static unsigned char K052109_romsubbank,K052109_scrollctrl;
  1527. static struct tilemap *K052109_tilemap[3];
  1528.  
  1529.  
  1530.  
  1531. /***************************************************************************
  1532.  
  1533.   Callbacks for the TileMap code
  1534.  
  1535. ***************************************************************************/
  1536.  
  1537. /*
  1538.   data format:
  1539.   video RAM    xxxxxxxx  tile number (low 8 bits)
  1540.   color RAM    xxxx----  depends on external connections (usually color and banking)
  1541.   color RAM    ----xx--  bank select (0-3): these bits are replaced with the 2
  1542.                          bottom bits of the bank register before being placed on
  1543.                          the output pins. The other two bits of the bank register are
  1544.                          placed on the CAB1 and CAB2 output pins.
  1545.   color RAM    ------xx  depends on external connections (usually banking, flip)
  1546. */
  1547.  
  1548. static void tilemap0_preupdate(void)
  1549. {
  1550.     colorram = K052109_colorram_F;
  1551.     videoram1 = K052109_videoram_F;
  1552.     videoram2 = K052109_videoram2_F;
  1553.     layer = 0;
  1554. }
  1555.  
  1556. static void tilemap1_preupdate(void)
  1557. {
  1558.     colorram = K052109_colorram_A;
  1559.     videoram1 = K052109_videoram_A;
  1560.     videoram2 = K052109_videoram2_A;
  1561.     layer = 1;
  1562. }
  1563.  
  1564. static void tilemap2_preupdate(void)
  1565. {
  1566.     colorram = K052109_colorram_B;
  1567.     videoram1 = K052109_videoram_B;
  1568.     videoram2 = K052109_videoram2_B;
  1569.     layer = 2;
  1570. }
  1571.  
  1572. static void K052109_get_tile_info(int tile_index)
  1573. {
  1574.     int flipy = 0;
  1575.     int code = videoram1[tile_index] + 256 * videoram2[tile_index];
  1576.     int color = colorram[tile_index];
  1577.     int bank = K052109_charrombank[(color & 0x0c) >> 2];
  1578. if (has_extra_video_ram) bank = (color & 0x0c) >> 2;    /* kludge for X-Men */
  1579.     color = (color & 0xf3) | ((bank & 0x03) << 2);
  1580.     bank >>= 2;
  1581.  
  1582.     flipy = color & 0x02;
  1583.  
  1584.     tile_info.flags = 0;
  1585.  
  1586.     (*K052109_callback)(layer,bank,&code,&color);
  1587.  
  1588.     SET_TILE_INFO(K052109_gfxnum,code,color);
  1589.  
  1590.     /* if the callback set flip X but it is not enabled, turn it off */
  1591.     if (!(K052109_tileflip_enable & 1)) tile_info.flags &= ~TILE_FLIPX;
  1592.  
  1593.     /* if flip Y is enabled and the attribute but is set, turn it on */
  1594.     if (flipy && (K052109_tileflip_enable & 2)) tile_info.flags |= TILE_FLIPY;
  1595. }
  1596.  
  1597.  
  1598.  
  1599. int K052109_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
  1600.         void (*callback)(int tilemap,int bank,int *code,int *color))
  1601. {
  1602.     int gfx_index;
  1603.     static struct GfxLayout charlayout =
  1604.     {
  1605.         8,8,
  1606.         0,                /* filled in later */
  1607.         4,
  1608.         { 0, 0, 0, 0 },    /* filled in later */
  1609.         { 0, 1, 2, 3, 4, 5, 6, 7 },
  1610.         { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
  1611.         32*8
  1612.     };
  1613.  
  1614.  
  1615.     /* find first empty slot to decode gfx */
  1616.     for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
  1617.         if (Machine->gfx[gfx_index] == 0)
  1618.             break;
  1619.     if (gfx_index == MAX_GFX_ELEMENTS)
  1620.         return 1;
  1621.  
  1622.     /* tweak the structure for the number of tiles we have */
  1623.     charlayout.total = memory_region_length(gfx_memory_region) / 32;
  1624.     charlayout.planeoffset[0] = plane3 * 8;
  1625.     charlayout.planeoffset[1] = plane2 * 8;
  1626.     charlayout.planeoffset[2] = plane1 * 8;
  1627.     charlayout.planeoffset[3] = plane0 * 8;
  1628.  
  1629.     /* decode the graphics */
  1630.     Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
  1631.     if (!Machine->gfx[gfx_index])
  1632.         return 1;
  1633.  
  1634.     /* set the color information */
  1635.     Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
  1636.     Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
  1637.  
  1638.     K052109_memory_region = gfx_memory_region;
  1639.     K052109_gfxnum = gfx_index;
  1640.     K052109_callback = callback;
  1641.     K052109_RMRD_line = CLEAR_LINE;
  1642.  
  1643.     has_extra_video_ram = 0;
  1644.  
  1645.     K052109_tilemap[0] = tilemap_create(K052109_get_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
  1646.     K052109_tilemap[1] = tilemap_create(K052109_get_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
  1647.     K052109_tilemap[2] = tilemap_create(K052109_get_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
  1648.  
  1649.     K052109_ram = malloc(0x6000);
  1650.  
  1651.     if (!K052109_ram || !K052109_tilemap[0] || !K052109_tilemap[1] || !K052109_tilemap[2])
  1652.     {
  1653.         K052109_vh_stop();
  1654.         return 1;
  1655.     }
  1656.  
  1657.     memset(K052109_ram,0,0x6000);
  1658.  
  1659.     K052109_colorram_F = &K052109_ram[0x0000];
  1660.     K052109_colorram_A = &K052109_ram[0x0800];
  1661.     K052109_colorram_B = &K052109_ram[0x1000];
  1662.     K052109_videoram_F = &K052109_ram[0x2000];
  1663.     K052109_videoram_A = &K052109_ram[0x2800];
  1664.     K052109_videoram_B = &K052109_ram[0x3000];
  1665.     K052109_videoram2_F = &K052109_ram[0x4000];
  1666.     K052109_videoram2_A = &K052109_ram[0x4800];
  1667.     K052109_videoram2_B = &K052109_ram[0x5000];
  1668.  
  1669.     K052109_tilemap[0]->transparent_pen = 0;
  1670.     K052109_tilemap[1]->transparent_pen = 0;
  1671.     K052109_tilemap[2]->transparent_pen = 0;
  1672.  
  1673.     return 0;
  1674. }
  1675.  
  1676. void K052109_vh_stop(void)
  1677. {
  1678.     free(K052109_ram);
  1679.     K052109_ram = 0;
  1680. }
  1681.  
  1682.  
  1683.  
  1684. READ_HANDLER( K052109_r )
  1685. {
  1686.     if (K052109_RMRD_line == CLEAR_LINE)
  1687.     {
  1688.         if ((offset & 0x1fff) >= 0x1800)
  1689.         {
  1690.             if (offset >= 0x180c && offset < 0x1834)
  1691.             {    /* A y scroll */    }
  1692.             else if (offset >= 0x1a00 && offset < 0x1c00)
  1693.             {    /* A x scroll */    }
  1694.             else if (offset == 0x1d00)
  1695.             {    /* read for bitwise operations before writing */    }
  1696.             else if (offset >= 0x380c && offset < 0x3834)
  1697.             {    /* B y scroll */    }
  1698.             else if (offset >= 0x3a00 && offset < 0x3c00)
  1699.             {    /* B x scroll */    }
  1700.             else
  1701. logerror("%04x: read from unknown 052109 address %04x\n",cpu_get_pc(),offset);
  1702.         }
  1703.  
  1704.         return K052109_ram[offset];
  1705.     }
  1706.     else    /* Punk Shot and TMNT read from 0000-1fff, Aliens from 2000-3fff */
  1707.     {
  1708.         int code = (offset & 0x1fff) >> 5;
  1709.         int color = K052109_romsubbank;
  1710.         int bank = K052109_charrombank[(color & 0x0c) >> 2] >> 2;   /* discard low bits (TMNT) */
  1711.         int addr;
  1712.  
  1713. if (has_extra_video_ram) code |= color << 8;    /* kludge for X-Men */
  1714. else
  1715.         (*K052109_callback)(0,bank,&code,&color);
  1716.  
  1717.         addr = (code << 5) + (offset & 0x1f);
  1718.         addr &= memory_region_length(K052109_memory_region)-1;
  1719.  
  1720. #if 0
  1721.     usrintf_showmessage("%04x: off%04x sub%02x (bnk%x) adr%06x",cpu_get_pc(),offset,K052109_romsubbank,bank,addr);
  1722. #endif
  1723.  
  1724.         return memory_region(K052109_memory_region)[addr];
  1725.     }
  1726. }
  1727.  
  1728. WRITE_HANDLER( K052109_w )
  1729. {
  1730.     if ((offset & 0x1fff) < 0x1800) /* tilemap RAM */
  1731.     {
  1732.         if (K052109_ram[offset] != data)
  1733.         {
  1734.             if (offset >= 0x4000) has_extra_video_ram = 1;  /* kludge for X-Men */
  1735.             K052109_ram[offset] = data;
  1736.             tilemap_mark_tile_dirty(K052109_tilemap[(offset & 0x1800) >> 11],offset & 0x7ff);
  1737.         }
  1738.     }
  1739.     else    /* control registers */
  1740.     {
  1741.         K052109_ram[offset] = data;
  1742.  
  1743.         if (offset >= 0x180c && offset < 0x1834)
  1744.         {    /* A y scroll */    }
  1745.         else if (offset >= 0x1a00 && offset < 0x1c00)
  1746.         {    /* A x scroll */    }
  1747.         else if (offset == 0x1c80)
  1748.         {
  1749. if (K052109_scrollctrl != data)
  1750. {
  1751. #if 0
  1752. usrintf_showmessage("scrollcontrol = %02x",data);
  1753. #endif
  1754. logerror("%04x: rowscrollcontrol = %02x\n",cpu_get_pc(),data);
  1755.             K052109_scrollctrl = data;
  1756. }
  1757.         }
  1758.         else if (offset == 0x1d00)
  1759.         {
  1760. #if VERBOSE
  1761. logerror("%04x: 052109 register 1d00 = %02x\n",cpu_get_pc(),data);
  1762. #endif
  1763.             /* bit 2 = irq enable */
  1764.             /* the custom chip can also generate NMI and FIRQ, for use with a 6809 */
  1765.             K052109_irq_enabled = data & 0x04;
  1766.         }
  1767.         else if (offset == 0x1d80)
  1768.         {
  1769.             int dirty = 0;
  1770.  
  1771.             if (K052109_charrombank[0] != (data & 0x0f)) dirty |= 1;
  1772.             if (K052109_charrombank[1] != ((data >> 4) & 0x0f)) dirty |= 2;
  1773.             if (dirty)
  1774.             {
  1775.                 int i;
  1776.  
  1777.                 K052109_charrombank[0] = data & 0x0f;
  1778.                 K052109_charrombank[1] = (data >> 4) & 0x0f;
  1779.  
  1780.                 for (i = 0;i < 0x1800;i++)
  1781.                 {
  1782.                     int bank = (K052109_ram[i]&0x0c) >> 2;
  1783.                     if ((bank == 0 && (dirty & 1)) || (bank == 1 && dirty & 2))
  1784.                     {
  1785.                         tilemap_mark_tile_dirty(K052109_tilemap[(i & 0x1800) >> 11],i & 0x7ff);
  1786.                     }
  1787.                 }
  1788.             }
  1789.         }
  1790.         else if (offset == 0x1e00)
  1791.         {
  1792. logerror("%04x: 052109 register 1e00 = %02x\n",cpu_get_pc(),data);
  1793.             K052109_romsubbank = data;
  1794.         }
  1795.         else if (offset == 0x1e80)
  1796.         {
  1797. if ((data & 0xfe)) logerror("%04x: 052109 register 1e80 = %02x\n",cpu_get_pc(),data);
  1798.             tilemap_set_flip(K052109_tilemap[0],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
  1799.             tilemap_set_flip(K052109_tilemap[1],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
  1800.             tilemap_set_flip(K052109_tilemap[2],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
  1801.             if (K052109_tileflip_enable != ((data & 0x06) >> 1))
  1802.             {
  1803.                 K052109_tileflip_enable = ((data & 0x06) >> 1);
  1804.  
  1805.                 tilemap_mark_all_tiles_dirty(K052109_tilemap[0]);
  1806.                 tilemap_mark_all_tiles_dirty(K052109_tilemap[1]);
  1807.                 tilemap_mark_all_tiles_dirty(K052109_tilemap[2]);
  1808.             }
  1809.         }
  1810.         else if (offset == 0x1f00)
  1811.         {
  1812.             int dirty = 0;
  1813.  
  1814.             if (K052109_charrombank[2] != (data & 0x0f)) dirty |= 1;
  1815.             if (K052109_charrombank[3] != ((data >> 4) & 0x0f)) dirty |= 2;
  1816.             if (dirty)
  1817.             {
  1818.                 int i;
  1819.  
  1820.                 K052109_charrombank[2] = data & 0x0f;
  1821.                 K052109_charrombank[3] = (data >> 4) & 0x0f;
  1822.  
  1823.                 for (i = 0;i < 0x1800;i++)
  1824.                 {
  1825.                     int bank = (K052109_ram[i] & 0x0c) >> 2;
  1826.                     if ((bank == 2 && (dirty & 1)) || (bank == 3 && dirty & 2))
  1827.                         tilemap_mark_tile_dirty(K052109_tilemap[(i & 0x1800) >> 11],i & 0x7ff);
  1828.                 }
  1829.             }
  1830.         }
  1831.         else if (offset >= 0x380c && offset < 0x3834)
  1832.         {    /* B y scroll */    }
  1833.         else if (offset >= 0x3a00 && offset < 0x3c00)
  1834.         {    /* B x scroll */    }
  1835.         else
  1836. logerror("%04x: write %02x to unknown 052109 address %04x\n",cpu_get_pc(),data,offset);
  1837.     }
  1838. }
  1839.  
  1840. void K052109_set_RMRD_line(int state)
  1841. {
  1842.     K052109_RMRD_line = state;
  1843. }
  1844.  
  1845.  
  1846. void K052109_tilemap_update(void)
  1847. {
  1848. #if 0
  1849. {
  1850. usrintf_showmessage("%x %x %x %x",
  1851.     K052109_charrombank[0],
  1852.     K052109_charrombank[1],
  1853.     K052109_charrombank[2],
  1854.     K052109_charrombank[3]);
  1855. }
  1856. #endif
  1857.     if ((K052109_scrollctrl & 0x03) == 0x02)
  1858.     {
  1859.         int xscroll,yscroll,offs;
  1860.         unsigned char *scrollram = &K052109_ram[0x1a00];
  1861.  
  1862.  
  1863.         tilemap_set_scroll_rows(K052109_tilemap[1],256);
  1864.         tilemap_set_scroll_cols(K052109_tilemap[1],1);
  1865.         yscroll = K052109_ram[0x180c];
  1866.         tilemap_set_scrolly(K052109_tilemap[1],0,yscroll);
  1867.         for (offs = 0;offs < 256;offs++)
  1868.         {
  1869.             xscroll = scrollram[2*(offs&0xfff8)+0] + 256 * scrollram[2*(offs&0xfff8)+1];
  1870.             xscroll -= 6;
  1871.             tilemap_set_scrollx(K052109_tilemap[1],(offs+yscroll)&0xff,xscroll);
  1872.         }
  1873.     }
  1874.     else if ((K052109_scrollctrl & 0x03) == 0x03)
  1875.     {
  1876.         int xscroll,yscroll,offs;
  1877.         unsigned char *scrollram = &K052109_ram[0x1a00];
  1878.  
  1879.  
  1880.         tilemap_set_scroll_rows(K052109_tilemap[1],256);
  1881.         tilemap_set_scroll_cols(K052109_tilemap[1],1);
  1882.         yscroll = K052109_ram[0x180c];
  1883.         tilemap_set_scrolly(K052109_tilemap[1],0,yscroll);
  1884.         for (offs = 0;offs < 256;offs++)
  1885.         {
  1886.             xscroll = scrollram[2*offs+0] + 256 * scrollram[2*offs+1];
  1887.             xscroll -= 6;
  1888.             tilemap_set_scrollx(K052109_tilemap[1],(offs+yscroll)&0xff,xscroll);
  1889.         }
  1890.     }
  1891.     else if ((K052109_scrollctrl & 0x04) == 0x04)
  1892.     {
  1893.         int xscroll,yscroll,offs;
  1894.         unsigned char *scrollram = &K052109_ram[0x1800];
  1895.  
  1896.  
  1897.         tilemap_set_scroll_rows(K052109_tilemap[1],1);
  1898.         tilemap_set_scroll_cols(K052109_tilemap[1],512);
  1899.         xscroll = K052109_ram[0x1a00] + 256 * K052109_ram[0x1a01];
  1900.         xscroll -= 6;
  1901.         tilemap_set_scrollx(K052109_tilemap[1],0,xscroll);
  1902.         for (offs = 0;offs < 512;offs++)
  1903.         {
  1904.             yscroll = scrollram[offs/8];
  1905.             tilemap_set_scrolly(K052109_tilemap[1],(offs+xscroll)&0x1ff,yscroll);
  1906.         }
  1907.     }
  1908.     else
  1909.     {
  1910.         int xscroll,yscroll;
  1911.         unsigned char *scrollram = &K052109_ram[0x1a00];
  1912.  
  1913.  
  1914.         tilemap_set_scroll_rows(K052109_tilemap[1],1);
  1915.         tilemap_set_scroll_cols(K052109_tilemap[1],1);
  1916.         xscroll = scrollram[0] + 256 * scrollram[1];
  1917.         xscroll -= 6;
  1918.         yscroll = K052109_ram[0x180c];
  1919.         tilemap_set_scrollx(K052109_tilemap[1],0,xscroll);
  1920.         tilemap_set_scrolly(K052109_tilemap[1],0,yscroll);
  1921.     }
  1922.  
  1923.     if ((K052109_scrollctrl & 0x18) == 0x10)
  1924.     {
  1925.         int xscroll,yscroll,offs;
  1926.         unsigned char *scrollram = &K052109_ram[0x3a00];
  1927.  
  1928.  
  1929.         tilemap_set_scroll_rows(K052109_tilemap[2],256);
  1930.         tilemap_set_scroll_cols(K052109_tilemap[2],1);
  1931.         yscroll = K052109_ram[0x380c];
  1932.         tilemap_set_scrolly(K052109_tilemap[2],0,yscroll);
  1933.         for (offs = 0;offs < 256;offs++)
  1934.         {
  1935.             xscroll = scrollram[2*(offs&0xfff8)+0] + 256 * scrollram[2*(offs&0xfff8)+1];
  1936.             xscroll -= 6;
  1937.             tilemap_set_scrollx(K052109_tilemap[2],(offs+yscroll)&0xff,xscroll);
  1938.         }
  1939.     }
  1940.     else if ((K052109_scrollctrl & 0x18) == 0x18)
  1941.     {
  1942.         int xscroll,yscroll,offs;
  1943.         unsigned char *scrollram = &K052109_ram[0x3a00];
  1944.  
  1945.  
  1946.         tilemap_set_scroll_rows(K052109_tilemap[2],256);
  1947.         tilemap_set_scroll_cols(K052109_tilemap[2],1);
  1948.         yscroll = K052109_ram[0x380c];
  1949.         tilemap_set_scrolly(K052109_tilemap[2],0,yscroll);
  1950.         for (offs = 0;offs < 256;offs++)
  1951.         {
  1952.             xscroll = scrollram[2*offs+0] + 256 * scrollram[2*offs+1];
  1953.             xscroll -= 6;
  1954.             tilemap_set_scrollx(K052109_tilemap[2],(offs+yscroll)&0xff,xscroll);
  1955.         }
  1956.     }
  1957.     else if ((K052109_scrollctrl & 0x20) == 0x20)
  1958.     {
  1959.         int xscroll,yscroll,offs;
  1960.         unsigned char *scrollram = &K052109_ram[0x3800];
  1961.  
  1962.  
  1963.         tilemap_set_scroll_rows(K052109_tilemap[2],1);
  1964.         tilemap_set_scroll_cols(K052109_tilemap[2],512);
  1965.         xscroll = K052109_ram[0x3a00] + 256 * K052109_ram[0x3a01];
  1966.         xscroll -= 6;
  1967.         tilemap_set_scrollx(K052109_tilemap[2],0,xscroll);
  1968.         for (offs = 0;offs < 512;offs++)
  1969.         {
  1970.             yscroll = scrollram[offs/8];
  1971.             tilemap_set_scrolly(K052109_tilemap[2],(offs+xscroll)&0x1ff,yscroll);
  1972.         }
  1973.     }
  1974.     else
  1975.     {
  1976.         int xscroll,yscroll;
  1977.         unsigned char *scrollram = &K052109_ram[0x3a00];
  1978.  
  1979.  
  1980.         tilemap_set_scroll_rows(K052109_tilemap[2],1);
  1981.         tilemap_set_scroll_cols(K052109_tilemap[2],1);
  1982.         xscroll = scrollram[0] + 256 * scrollram[1];
  1983.         xscroll -= 6;
  1984.         yscroll = K052109_ram[0x380c];
  1985.         tilemap_set_scrollx(K052109_tilemap[2],0,xscroll);
  1986.         tilemap_set_scrolly(K052109_tilemap[2],0,yscroll);
  1987.     }
  1988.  
  1989.     tilemap0_preupdate(); tilemap_update(K052109_tilemap[0]);
  1990.     tilemap1_preupdate(); tilemap_update(K052109_tilemap[1]);
  1991.     tilemap2_preupdate(); tilemap_update(K052109_tilemap[2]);
  1992.  
  1993. #ifdef MAME_DEBUG
  1994. if ((K052109_scrollctrl & 0x03) == 0x01 ||
  1995.         (K052109_scrollctrl & 0x18) == 0x08 ||
  1996.         ((K052109_scrollctrl & 0x04) && (K052109_scrollctrl & 0x03)) ||
  1997.         ((K052109_scrollctrl & 0x20) && (K052109_scrollctrl & 0x18)) ||
  1998.         (K052109_scrollctrl & 0xc0) != 0)
  1999.     usrintf_showmessage("scrollcontrol = %02x",K052109_scrollctrl);
  2000. #endif
  2001.  
  2002. #if 0
  2003. if (keyboard_pressed(KEYCODE_F))
  2004. {
  2005.     FILE *fp;
  2006.     fp=fopen("TILE.DMP", "w+b");
  2007.     if (fp)
  2008.     {
  2009.         fwrite(K052109_ram, 0x6000, 1, fp);
  2010.         usrintf_showmessage("saved");
  2011.         fclose(fp);
  2012.     }
  2013. }
  2014. #endif
  2015. }
  2016.  
  2017. void K052109_tilemap_draw(struct osd_bitmap *bitmap,int num,int flags)
  2018. {
  2019.     tilemap_draw(bitmap,K052109_tilemap[num],flags);
  2020. }
  2021.  
  2022. int K052109_is_IRQ_enabled(void)
  2023. {
  2024.     return K052109_irq_enabled;
  2025. }
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033. static int K051960_memory_region;
  2034. static struct GfxElement *K051960_gfx;
  2035. static void (*K051960_callback)(int *code,int *color,int *priority);
  2036. static int K051960_romoffset;
  2037. static int K051960_spriteflip,K051960_readroms,K051960_force_shadows;
  2038. static unsigned char K051960_spriterombank[3];
  2039. static unsigned char *K051960_ram;
  2040. static int K051960_irq_enabled, K051960_nmi_enabled;
  2041.  
  2042.  
  2043. int K051960_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
  2044.         void (*callback)(int *code,int *color,int *priority))
  2045. {
  2046.     int gfx_index;
  2047.     static struct GfxLayout spritelayout =
  2048.     {
  2049.         16,16,
  2050.         0,                /* filled in later */
  2051.         4,
  2052.         { 0, 0, 0, 0 },    /* filled in later */
  2053.         { 0, 1, 2, 3, 4, 5, 6, 7,
  2054.                 8*32+0, 8*32+1, 8*32+2, 8*32+3, 8*32+4, 8*32+5, 8*32+6, 8*32+7 },
  2055.         { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
  2056.                 16*32, 17*32, 18*32, 19*32, 20*32, 21*32, 22*32, 23*32 },
  2057.         128*8
  2058.     };
  2059.  
  2060.  
  2061.     /* find first empty slot to decode gfx */
  2062.     for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
  2063.         if (Machine->gfx[gfx_index] == 0)
  2064.             break;
  2065.     if (gfx_index == MAX_GFX_ELEMENTS)
  2066.         return 1;
  2067.  
  2068.     /* tweak the structure for the number of tiles we have */
  2069.     spritelayout.total = memory_region_length(gfx_memory_region) / 128;
  2070.     spritelayout.planeoffset[0] = plane0 * 8;
  2071.     spritelayout.planeoffset[1] = plane1 * 8;
  2072.     spritelayout.planeoffset[2] = plane2 * 8;
  2073.     spritelayout.planeoffset[3] = plane3 * 8;
  2074.  
  2075.     /* decode the graphics */
  2076.     Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
  2077.     if (!Machine->gfx[gfx_index])
  2078.         return 1;
  2079.  
  2080.     /* set the color information */
  2081.     Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
  2082.     Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
  2083.  
  2084.     K051960_memory_region = gfx_memory_region;
  2085.     K051960_gfx = Machine->gfx[gfx_index];
  2086.     K051960_callback = callback;
  2087.     K051960_ram = malloc(0x400);
  2088.     if (!K051960_ram) return 1;
  2089.     memset(K051960_ram,0,0x400);
  2090.     K051960_force_shadows = 0;
  2091.  
  2092.     return 0;
  2093. }
  2094.  
  2095. void K051960_vh_stop(void)
  2096. {
  2097.     free(K051960_ram);
  2098.     K051960_ram = 0;
  2099. }
  2100.  
  2101.  
  2102. static int K051960_fetchromdata(int byte)
  2103. {
  2104.     int code,color,pri,off1,addr;
  2105.  
  2106.  
  2107.     addr = K051960_romoffset + (K051960_spriterombank[0] << 8) +
  2108.             ((K051960_spriterombank[1] & 0x03) << 16);
  2109.     code = (addr & 0x3ffe0) >> 5;
  2110.     off1 = addr & 0x1f;
  2111.     color = ((K051960_spriterombank[1] & 0xfc) >> 2) + ((K051960_spriterombank[2] & 0x03) << 6);
  2112.     pri = 0;
  2113.     (*K051960_callback)(&code,&color,&pri);
  2114.  
  2115.     addr = (code << 7) | (off1 << 2) | byte;
  2116.     addr &= memory_region_length(K051960_memory_region)-1;
  2117.  
  2118. #if 0
  2119.     usrintf_showmessage("%04x: addr %06x",cpu_get_pc(),addr);
  2120. #endif
  2121.  
  2122.     return memory_region(K051960_memory_region)[addr];
  2123. }
  2124.  
  2125. READ_HANDLER( K051960_r )
  2126. {
  2127.     if (K051960_readroms)
  2128.     {
  2129.         /* the 051960 remembers the last address read and uses it when reading the sprite ROMs */
  2130.         K051960_romoffset = (offset & 0x3fc) >> 2;
  2131.         return K051960_fetchromdata(offset & 3);    /* only 88 Games reads the ROMs from here */
  2132.     }
  2133.     else
  2134.         return K051960_ram[offset];
  2135. }
  2136.  
  2137. WRITE_HANDLER( K051960_w )
  2138. {
  2139.     K051960_ram[offset] = data;
  2140. }
  2141.  
  2142. READ_HANDLER( K051960_word_r )
  2143. {
  2144.     return K051960_r(offset + 1) | (K051960_r(offset) << 8);
  2145. }
  2146.  
  2147. WRITE_HANDLER( K051960_word_w )
  2148. {
  2149.     if ((data & 0xff000000) == 0)
  2150.         K051960_w(offset,(data >> 8) & 0xff);
  2151.     if ((data & 0x00ff0000) == 0)
  2152.         K051960_w(offset + 1,data & 0xff);
  2153. }
  2154.  
  2155. READ_HANDLER( K051937_r )
  2156. {
  2157.     if (K051960_readroms && offset >= 4 && offset < 8)
  2158.     {
  2159.         return K051960_fetchromdata(offset & 3);
  2160.     }
  2161.     else
  2162.     {
  2163.         if (offset == 0)
  2164.         {
  2165.             static int counter;
  2166.  
  2167.             /* some games need bit 0 to pulse */
  2168.             return (counter++) & 1;
  2169.         }
  2170. logerror("%04x: read unknown 051937 address %x\n",cpu_get_pc(),offset);
  2171.         return 0;
  2172.     }
  2173. }
  2174.  
  2175. WRITE_HANDLER( K051937_w )
  2176. {
  2177.     if (offset == 0)
  2178.     {
  2179. #ifdef MAME_DEBUG
  2180. if (data & 0xc6)
  2181.     usrintf_showmessage("051937 reg 00 = %02x",data);
  2182. #endif
  2183.         /* bit 0 is IRQ enable */
  2184.         K051960_irq_enabled = (data & 0x01);
  2185.  
  2186.         /* bit 1: probably FIRQ enable */
  2187.  
  2188.         /* bit 2 is NMI enable */
  2189.         K051960_nmi_enabled = (data & 0x04);
  2190.  
  2191.         /* bit 3 = flip screen */
  2192.         K051960_spriteflip = data & 0x08;
  2193.  
  2194.         /* bit 4 used by Devastators and TMNT, unknown */
  2195.  
  2196.         /* bit 5 = enable gfx ROM reading */
  2197.         K051960_readroms = data & 0x20;
  2198. #if VERBOSE
  2199. logerror("%04x: write %02x to 051937 address %x\n",cpu_get_pc(),data,offset);
  2200. #endif
  2201.     }
  2202.     else if (offset == 1)
  2203.     {
  2204. #if 0
  2205.     usrintf_showmessage("%04x: write %02x to 051937 address %x",cpu_get_pc(),data,offset);
  2206. #endif
  2207. logerror("%04x: write %02x to unknown 051937 address %x\n",cpu_get_pc(),data,offset);
  2208.         K051960_force_shadows = data & 0x02;
  2209.     }
  2210.     else if (offset >= 2 && offset < 5)
  2211.     {
  2212.         K051960_spriterombank[offset - 2] = data;
  2213.     }
  2214.     else
  2215.     {
  2216. #if 0
  2217.     usrintf_showmessage("%04x: write %02x to 051937 address %x",cpu_get_pc(),data,offset);
  2218. #endif
  2219. logerror("%04x: write %02x to unknown 051937 address %x\n",cpu_get_pc(),data,offset);
  2220.     }
  2221. }
  2222.  
  2223. READ_HANDLER( K051937_word_r )
  2224. {
  2225.     return K051937_r(offset + 1) | (K051937_r(offset) << 8);
  2226. }
  2227.  
  2228. WRITE_HANDLER( K051937_word_w )
  2229. {
  2230.     if ((data & 0xff000000) == 0)
  2231.         K051937_w(offset,(data >> 8) & 0xff);
  2232.     if ((data & 0x00ff0000) == 0)
  2233.         K051937_w(offset + 1,data & 0xff);
  2234. }
  2235.  
  2236.  
  2237. /*
  2238.  * Sprite Format
  2239.  * ------------------
  2240.  *
  2241.  * Byte | Bit(s)   | Use
  2242.  * -----+-76543210-+----------------
  2243.  *   0  | x------- | active (show this sprite)
  2244.  *   0  | -xxxxxxx | priority order
  2245.  *   1  | xxx----- | sprite size (see below)
  2246.  *   1  | ---xxxxx | sprite code (high 5 bits)
  2247.  *   2  | xxxxxxxx | sprite code (low 8 bits)
  2248.  *   3  | xxxxxxxx | "color", but depends on external connections (see below)
  2249.  *   4  | xxxxxx-- | zoom y (0 = normal, >0 = shrink)
  2250.  *   4  | ------x- | flip y
  2251.  *   4  | -------x | y position (high bit)
  2252.  *   5  | xxxxxxxx | y position (low 8 bits)
  2253.  *   6  | xxxxxx-- | zoom x (0 = normal, >0 = shrink)
  2254.  *   6  | ------x- | flip x
  2255.  *   6  | -------x | x position (high bit)
  2256.  *   7  | xxxxxxxx | x position (low 8 bits)
  2257.  *
  2258.  * Example of "color" field for Punk Shot:
  2259.  *   3  | x------- | shadow
  2260.  *   3  | -xx----- | priority
  2261.  *   3  | ---x---- | use second gfx ROM bank
  2262.  *   3  | ----xxxx | color code
  2263.  *
  2264.  * shadow enables transparent shadows. Note that it applies to pen 0x0f ONLY.
  2265.  * The rest of the sprite remains normal.
  2266.  * Note that Aliens also uses the shadow bit to select the second sprite bank.
  2267.  */
  2268.  
  2269. void K051960_sprites_draw(struct osd_bitmap *bitmap,int min_priority,int max_priority)
  2270. {
  2271. #define NUM_SPRITES 128
  2272.     int offs,pri_code;
  2273.     int sortedlist[NUM_SPRITES];
  2274.  
  2275.     for (offs = 0;offs < NUM_SPRITES;offs++)
  2276.         sortedlist[offs] = -1;
  2277.  
  2278.     /* prebuild a sorted table */
  2279.     for (offs = 0;offs < 0x400;offs += 8)
  2280.     {
  2281.         if (K051960_ram[offs] & 0x80)
  2282.         {
  2283.             if (max_priority == -1)    /* draw front to back when using priority buffer */
  2284.                 sortedlist[(K051960_ram[offs] & 0x7f) ^ 0x7f] = offs;
  2285.             else
  2286.                 sortedlist[K051960_ram[offs] & 0x7f] = offs;
  2287.         }
  2288.     }
  2289.  
  2290.     for (pri_code = 0;pri_code < NUM_SPRITES;pri_code++)
  2291.     {
  2292.         int ox,oy,code,color,pri,size,w,h,x,y,flipx,flipy,zoomx,zoomy;
  2293.         /* sprites can be grouped up to 8x8. The draw order is
  2294.              0  1  4  5 16 17 20 21
  2295.              2  3  6  7 18 19 22 23
  2296.              8  9 12 13 24 25 28 29
  2297.             10 11 14 15 26 27 30 31
  2298.             32 33 36 37 48 49 52 53
  2299.             34 35 38 39 50 51 54 55
  2300.             40 41 44 45 56 57 60 61
  2301.             42 43 46 47 58 59 62 63
  2302.         */
  2303.         static int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
  2304.         static int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
  2305.         static int width[8] =  { 1, 2, 1, 2, 4, 2, 4, 8 };
  2306.         static int height[8] = { 1, 1, 2, 2, 2, 4, 4, 8 };
  2307.  
  2308.  
  2309.         offs = sortedlist[pri_code];
  2310.         if (offs == -1) continue;
  2311.  
  2312.         code = K051960_ram[offs+2] + ((K051960_ram[offs+1] & 0x1f) << 8);
  2313.         color = K051960_ram[offs+3] & 0xff;
  2314.         pri = 0;
  2315.  
  2316.         (*K051960_callback)(&code,&color,&pri);
  2317.  
  2318.         if (max_priority != -1)
  2319.             if (pri < min_priority || pri > max_priority) continue;
  2320.  
  2321.         size = (K051960_ram[offs+1] & 0xe0) >> 5;
  2322.         w = width[size];
  2323.         h = height[size];
  2324.  
  2325.         if (w >= 2) code &= ~0x01;
  2326.         if (h >= 2) code &= ~0x02;
  2327.         if (w >= 4) code &= ~0x04;
  2328.         if (h >= 4) code &= ~0x08;
  2329.         if (w >= 8) code &= ~0x10;
  2330.         if (h >= 8) code &= ~0x20;
  2331.  
  2332.         ox = (256 * K051960_ram[offs+6] + K051960_ram[offs+7]) & 0x01ff;
  2333.         oy = 256 - ((256 * K051960_ram[offs+4] + K051960_ram[offs+5]) & 0x01ff);
  2334.         flipx = K051960_ram[offs+6] & 0x02;
  2335.         flipy = K051960_ram[offs+4] & 0x02;
  2336.         zoomx = (K051960_ram[offs+6] & 0xfc) >> 2;
  2337.         zoomy = (K051960_ram[offs+4] & 0xfc) >> 2;
  2338.         zoomx = 0x10000 / 128 * (128 - zoomx);
  2339.         zoomy = 0x10000 / 128 * (128 - zoomy);
  2340.  
  2341.         if (K051960_spriteflip)
  2342.         {
  2343.             ox = 512 - (zoomx * w >> 12) - ox;
  2344.             oy = 256 - (zoomy * h >> 12) - oy;
  2345.             flipx = !flipx;
  2346.             flipy = !flipy;
  2347.         }
  2348.  
  2349.         if (zoomx == 0x10000 && zoomy == 0x10000)
  2350.         {
  2351.             int sx,sy;
  2352.  
  2353.             for (y = 0;y < h;y++)
  2354.             {
  2355.                 sy = oy + 16 * y;
  2356.  
  2357.                 for (x = 0;x < w;x++)
  2358.                 {
  2359.                     int c = code;
  2360.  
  2361.                     sx = ox + 16 * x;
  2362.                     if (flipx) c += xoffset[(w-1-x)];
  2363.                     else c += xoffset[x];
  2364.                     if (flipy) c += yoffset[(h-1-y)];
  2365.                     else c += yoffset[y];
  2366.  
  2367.                     /* hack to simulate shadow */
  2368.                     if (K051960_force_shadows || (K051960_ram[offs+3] & 0x80))
  2369.                     {
  2370.                         int o = K051960_gfx->colortable[16*color+15];
  2371.                         K051960_gfx->colortable[16*color+15] = palette_transparent_pen;
  2372.                         if (max_priority == -1)
  2373.                             pdrawgfx(bitmap,K051960_gfx,
  2374.                                     c,
  2375.                                     color,
  2376.                                     flipx,flipy,
  2377.                                     sx & 0x1ff,sy,
  2378.                                     &Machine->drv->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,pri);
  2379.                         else
  2380.                             drawgfx(bitmap,K051960_gfx,
  2381.                                     c,
  2382.                                     color,
  2383.                                     flipx,flipy,
  2384.                                     sx & 0x1ff,sy,
  2385.                                     &Machine->drv->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001);
  2386.                         K051960_gfx->colortable[16*color+15] = o;
  2387.                     }
  2388.                     else
  2389.                     {
  2390.                         if (max_priority == -1)
  2391.                             pdrawgfx(bitmap,K051960_gfx,
  2392.                                     c,
  2393.                                     color,
  2394.                                     flipx,flipy,
  2395.                                     sx & 0x1ff,sy,
  2396.                                     &Machine->drv->visible_area,TRANSPARENCY_PEN,0,pri);
  2397.                         else
  2398.                             drawgfx(bitmap,K051960_gfx,
  2399.                                     c,
  2400.                                     color,
  2401.                                     flipx,flipy,
  2402.                                     sx & 0x1ff,sy,
  2403.                                     &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  2404.                     }
  2405.                 }
  2406.             }
  2407.         }
  2408.         else
  2409.         {
  2410.             int sx,sy,zw,zh;
  2411.  
  2412.             for (y = 0;y < h;y++)
  2413.             {
  2414.                 sy = oy + ((zoomy * y + (1<<11)) >> 12);
  2415.                 zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
  2416.  
  2417.                 for (x = 0;x < w;x++)
  2418.                 {
  2419.                     int c = code;
  2420.  
  2421.                     sx = ox + ((zoomx * x + (1<<11)) >> 12);
  2422.                     zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
  2423.                     if (flipx) c += xoffset[(w-1-x)];
  2424.                     else c += xoffset[x];
  2425.                     if (flipy) c += yoffset[(h-1-y)];
  2426.                     else c += yoffset[y];
  2427.  
  2428.                     /* hack to simulate shadow */
  2429.                     if (K051960_force_shadows || (K051960_ram[offs+3] & 0x80))
  2430.                     {
  2431.                         int o = K051960_gfx->colortable[16*color+15];
  2432.                         K051960_gfx->colortable[16*color+15] = palette_transparent_pen;
  2433.                         if (max_priority == -1)
  2434.                             pdrawgfxzoom(bitmap,K051960_gfx,
  2435.                                     c,
  2436.                                     color,
  2437.                                     flipx,flipy,
  2438.                                     sx & 0x1ff,sy,
  2439.                                     &Machine->drv->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,
  2440.                                     (zw << 16) / 16,(zh << 16) / 16,pri);
  2441.                         else
  2442.                             drawgfxzoom(bitmap,K051960_gfx,
  2443.                                     c,
  2444.                                     color,
  2445.                                     flipx,flipy,
  2446.                                     sx & 0x1ff,sy,
  2447.                                     &Machine->drv->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,
  2448.                                     (zw << 16) / 16,(zh << 16) / 16);
  2449.                         K051960_gfx->colortable[16*color+15] = o;
  2450.                     }
  2451.                     else
  2452.                     {
  2453.                         if (max_priority == -1)
  2454.                             pdrawgfxzoom(bitmap,K051960_gfx,
  2455.                                     c,
  2456.                                     color,
  2457.                                     flipx,flipy,
  2458.                                     sx & 0x1ff,sy,
  2459.                                     &Machine->drv->visible_area,TRANSPARENCY_PEN,0,
  2460.                                     (zw << 16) / 16,(zh << 16) / 16,pri);
  2461.                         else
  2462.                             drawgfxzoom(bitmap,K051960_gfx,
  2463.                                     c,
  2464.                                     color,
  2465.                                     flipx,flipy,
  2466.                                     sx & 0x1ff,sy,
  2467.                                     &Machine->drv->visible_area,TRANSPARENCY_PEN,0,
  2468.                                     (zw << 16) / 16,(zh << 16) / 16);
  2469.                     }
  2470.                 }
  2471.             }
  2472.         }
  2473.     }
  2474. #if 0
  2475. if (keyboard_pressed(KEYCODE_D))
  2476. {
  2477.     FILE *fp;
  2478.     fp=fopen("SPRITE.DMP", "w+b");
  2479.     if (fp)
  2480.     {
  2481.         fwrite(K051960_ram, 0x400, 1, fp);
  2482.         usrintf_showmessage("saved");
  2483.         fclose(fp);
  2484.     }
  2485. }
  2486. #endif
  2487. #undef NUM_SPRITES
  2488. }
  2489.  
  2490. void K051960_mark_sprites_colors(void)
  2491. {
  2492.     int offs,i;
  2493.  
  2494.     unsigned short palette_map[512];
  2495.  
  2496.     memset (palette_map, 0, sizeof (palette_map));
  2497.  
  2498.     /* sprites */
  2499.     for (offs = 0x400-8;offs >= 0;offs -= 8)
  2500.     {
  2501.         if (K051960_ram[offs] & 0x80)
  2502.         {
  2503.             int code,color,pri;
  2504.  
  2505.             code = K051960_ram[offs+2] + ((K051960_ram[offs+1] & 0x1f) << 8);
  2506.             color = (K051960_ram[offs+3] & 0xff);
  2507.             pri = 0;
  2508.             (*K051960_callback)(&code,&color,&pri);
  2509.             palette_map[color] |= 0xffff;
  2510.         }
  2511.     }
  2512.  
  2513.     /* now build the final table */
  2514.     for (i = 0; i < 512; i++)
  2515.     {
  2516.         int usage = palette_map[i], j;
  2517.         if (usage)
  2518.         {
  2519.             for (j = 1; j < 16; j++)
  2520.                 if (usage & (1 << j))
  2521.                     palette_used_colors[i * 16 + j] |= PALETTE_COLOR_VISIBLE;
  2522.         }
  2523.     }
  2524. }
  2525.  
  2526. int K051960_is_IRQ_enabled(void)
  2527. {
  2528.     return K051960_irq_enabled;
  2529. }
  2530.  
  2531. int K051960_is_NMI_enabled(void)
  2532. {
  2533.     return K051960_nmi_enabled;
  2534. }
  2535.  
  2536.  
  2537.  
  2538.  
  2539. READ_HANDLER( K052109_051960_r )
  2540. {
  2541.     if (K052109_RMRD_line == CLEAR_LINE)
  2542.     {
  2543.         if (offset >= 0x3800 && offset < 0x3808)
  2544.             return K051937_r(offset - 0x3800);
  2545.         else if (offset < 0x3c00)
  2546.             return K052109_r(offset);
  2547.         else
  2548.             return K051960_r(offset - 0x3c00);
  2549.     }
  2550.     else return K052109_r(offset);
  2551. }
  2552.  
  2553. WRITE_HANDLER( K052109_051960_w )
  2554. {
  2555.     if (offset >= 0x3800 && offset < 0x3808)
  2556.         K051937_w(offset - 0x3800,data);
  2557.     else if (offset < 0x3c00)
  2558.         K052109_w(offset,data);
  2559.     else
  2560.         K051960_w(offset - 0x3c00,data);
  2561. }
  2562.  
  2563.  
  2564.  
  2565.  
  2566.  
  2567. static int K053245_memory_region=2;
  2568. static struct GfxElement *K053245_gfx;
  2569. static void (*K053245_callback)(int *code,int *color,int *priority);
  2570. static int K053244_romoffset,K053244_rombank;
  2571. static int K053244_readroms;
  2572. static int K053245_flipscreenX,K053245_flipscreenY;
  2573. static int K053245_spriteoffsX,K053245_spriteoffsY;
  2574. static unsigned char *K053245_ram;
  2575.  
  2576. int K053245_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
  2577.         void (*callback)(int *code,int *color,int *priority))
  2578. {
  2579.     int gfx_index;
  2580.     static struct GfxLayout spritelayout =
  2581.     {
  2582.         16,16,
  2583.         0,                /* filled in later */
  2584.         4,
  2585.         { 0, 0, 0, 0 },    /* filled in later */
  2586.         { 0, 1, 2, 3, 4, 5, 6, 7,
  2587.                 8*32+0, 8*32+1, 8*32+2, 8*32+3, 8*32+4, 8*32+5, 8*32+6, 8*32+7 },
  2588.         { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
  2589.                 16*32, 17*32, 18*32, 19*32, 20*32, 21*32, 22*32, 23*32 },
  2590.         128*8
  2591.     };
  2592.  
  2593.  
  2594.     /* find first empty slot to decode gfx */
  2595.     for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
  2596.         if (Machine->gfx[gfx_index] == 0)
  2597.             break;
  2598.     if (gfx_index == MAX_GFX_ELEMENTS)
  2599.         return 1;
  2600.  
  2601.     /* tweak the structure for the number of tiles we have */
  2602.     spritelayout.total = memory_region_length(gfx_memory_region) / 128;
  2603.     spritelayout.planeoffset[0] = plane3 * 8;
  2604.     spritelayout.planeoffset[1] = plane2 * 8;
  2605.     spritelayout.planeoffset[2] = plane1 * 8;
  2606.     spritelayout.planeoffset[3] = plane0 * 8;
  2607.  
  2608.     /* decode the graphics */
  2609.     Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
  2610.     if (!Machine->gfx[gfx_index])
  2611.         return 1;
  2612.  
  2613.     /* set the color information */
  2614.     Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
  2615.     Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
  2616.  
  2617.     K053245_memory_region = gfx_memory_region;
  2618.     K053245_gfx = Machine->gfx[gfx_index];
  2619.     K053245_callback = callback;
  2620.     K053244_rombank = 0;
  2621.     K053245_ram = malloc(0x800);
  2622.     if (!K053245_ram) return 1;
  2623.  
  2624.     memset(K053245_ram,0,0x800);
  2625.  
  2626.     return 0;
  2627. }
  2628.  
  2629. void K053245_vh_stop(void)
  2630. {
  2631.     free(K053245_ram);
  2632.     K053245_ram = 0;
  2633. }
  2634.  
  2635. READ_HANDLER( K053245_word_r )
  2636. {
  2637.     return READ_WORD(&K053245_ram[offset]);
  2638. }
  2639.  
  2640. WRITE_HANDLER( K053245_word_w )
  2641. {
  2642.     COMBINE_WORD_MEM(&K053245_ram[offset],data);
  2643. }
  2644.  
  2645. READ_HANDLER( K053245_r )
  2646. {
  2647.     int shift = ((offset & 1) ^ 1) << 3;
  2648.     return (READ_WORD(&K053245_ram[offset & ~1]) >> shift) & 0xff;
  2649. }
  2650.  
  2651. WRITE_HANDLER( K053245_w )
  2652. {
  2653.     int shift = ((offset & 1) ^ 1) << 3;
  2654.     offset &= ~1;
  2655.     COMBINE_WORD_MEM(&K053245_ram[offset],(0xff000000 >> shift) | ((data & 0xff) << shift));
  2656. }
  2657.  
  2658. READ_HANDLER( K053244_r )
  2659. {
  2660.     if (K053244_readroms && offset >= 0x0c && offset < 0x10)
  2661.     {
  2662.         int addr;
  2663.  
  2664.  
  2665.         addr = 0x200000 * K053244_rombank + 4 * (K053244_romoffset & 0x7ffff) + ((offset & 3) ^ 1);
  2666.         addr &= memory_region_length(K053245_memory_region)-1;
  2667.  
  2668. #if 0
  2669.     usrintf_showmessage("%04x: offset %02x addr %06x",cpu_get_pc(),offset&3,addr);
  2670. #endif
  2671.  
  2672.         return memory_region(K053245_memory_region)[addr];
  2673.     }
  2674.     else
  2675.     {
  2676. logerror("%04x: read from unknown 053244 address %x\n",cpu_get_pc(),offset);
  2677.         return 0;
  2678.     }
  2679. }
  2680.  
  2681. WRITE_HANDLER( K053244_w )
  2682. {
  2683.     if (offset == 0x00)
  2684.         K053245_spriteoffsX = (K053245_spriteoffsX & 0x00ff) | (data << 8);
  2685.     else if (offset == 0x01)
  2686.         K053245_spriteoffsX = (K053245_spriteoffsX & 0xff00) | data;
  2687.     else if (offset == 0x02)
  2688.         K053245_spriteoffsY = (K053245_spriteoffsY & 0x00ff) | (data << 8);
  2689.     else if (offset == 0x03)
  2690.         K053245_spriteoffsY = (K053245_spriteoffsY & 0xff00) | data;
  2691.     else if (offset == 0x05)
  2692.     {
  2693. #ifdef MAME_DEBUG
  2694. if (data & 0xc8)
  2695.     usrintf_showmessage("053244 reg 05 = %02x",data);
  2696. #endif
  2697.         /* bit 0/1 = flip screen */
  2698.         K053245_flipscreenX = data & 0x01;
  2699.         K053245_flipscreenY = data & 0x02;
  2700.  
  2701.         /* bit 2 = unknown, Parodius uses it */
  2702.  
  2703.         /* bit 4 = enable gfx ROM reading */
  2704.         K053244_readroms = data & 0x10;
  2705.  
  2706.         /* bit 5 = unknown, Rollergames uses it */
  2707. #if VERBOSE
  2708. logerror("%04x: write %02x to 053244 address 5\n",cpu_get_pc(),data);
  2709. #endif
  2710.     }
  2711.     else if (offset >= 0x08 && offset < 0x0c)
  2712.     {
  2713.         offset = 8*((offset & 0x03) ^ 0x01);
  2714.         K053244_romoffset = (K053244_romoffset & ~(0xff << offset)) | (data << offset);
  2715.         return;
  2716.     }
  2717.     else
  2718. logerror("%04x: write %02x to unknown 053244 address %x\n",cpu_get_pc(),data,offset);
  2719. }
  2720.  
  2721. void K053244_bankselect(int bank)   /* used by TMNT2 for ROM testing */
  2722. {
  2723.     K053244_rombank = bank;
  2724. }
  2725.  
  2726. /*
  2727.  * Sprite Format
  2728.  * ------------------
  2729.  *
  2730.  * Word | Bit(s)           | Use
  2731.  * -----+-fedcba9876543210-+----------------
  2732.  *   0  | x--------------- | active (show this sprite)
  2733.  *   0  | -x-------------- | maintain aspect ratio (when set, zoom y acts on both axis)
  2734.  *   0  | --x------------- | flip y
  2735.  *   0  | ---x------------ | flip x
  2736.  *   0  | ----xxxx-------- | sprite size (see below)
  2737.  *   0  | ---------xxxxxxx | priority order
  2738.  *   1  | --xxxxxxxxxxxxxx | sprite code. We use an additional bit in TMNT2, but this is
  2739.  *                           probably not accurate (protection related so we can't verify)
  2740.  *   2  | ------xxxxxxxxxx | y position
  2741.  *   3  | ------xxxxxxxxxx | x position
  2742.  *   4  | xxxxxxxxxxxxxxxx | zoom y (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
  2743.  *   5  | xxxxxxxxxxxxxxxx | zoom x (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
  2744.  *   6  | ------x--------- | mirror y (top half is drawn as mirror image of the bottom)
  2745.  *   6  | -------x-------- | mirror x (right half is drawn as mirror image of the left)
  2746.  *   6  | --------x------- | shadow
  2747.  *   6  | ---------xxxxxxx | "color", but depends on external connections
  2748.  *   7  | ---------------- |
  2749.  *
  2750.  * shadow enables transparent shadows. Note that it applies to pen 0x0f ONLY.
  2751.  * The rest of the sprite remains normal.
  2752.  */
  2753.  
  2754. void K053245_sprites_draw(struct osd_bitmap *bitmap)
  2755. {
  2756. #define NUM_SPRITES 128
  2757.     int offs,pri_code;
  2758.     int sortedlist[NUM_SPRITES];
  2759.  
  2760.     for (offs = 0;offs < NUM_SPRITES;offs++)
  2761.         sortedlist[offs] = -1;
  2762.  
  2763.     /* prebuild a sorted table */
  2764.     for (offs = 0;offs < 0x800;offs += 16)
  2765.     {
  2766.         if (READ_WORD(&K053245_ram[offs]) & 0x8000)
  2767.         {
  2768.             sortedlist[READ_WORD(&K053245_ram[offs]) & 0x007f] = offs;
  2769.         }
  2770.     }
  2771.  
  2772.     for (pri_code = NUM_SPRITES-1;pri_code >= 0;pri_code--)
  2773.     {
  2774.         int ox,oy,color,code,size,w,h,x,y,flipx,flipy,mirrorx,mirrory,zoomx,zoomy,pri;
  2775.  
  2776.  
  2777.         offs = sortedlist[pri_code];
  2778.         if (offs == -1) continue;
  2779.  
  2780.         /* the following changes the sprite draw order from
  2781.              0  1  4  5 16 17 20 21
  2782.              2  3  6  7 18 19 22 23
  2783.              8  9 12 13 24 25 28 29
  2784.             10 11 14 15 26 27 30 31
  2785.             32 33 36 37 48 49 52 53
  2786.             34 35 38 39 50 51 54 55
  2787.             40 41 44 45 56 57 60 61
  2788.             42 43 46 47 58 59 62 63
  2789.  
  2790.             to
  2791.  
  2792.              0  1  2  3  4  5  6  7
  2793.              8  9 10 11 12 13 14 15
  2794.             16 17 18 19 20 21 22 23
  2795.             24 25 26 27 28 29 30 31
  2796.             32 33 34 35 36 37 38 39
  2797.             40 41 42 43 44 45 46 47
  2798.             48 49 50 51 52 53 54 55
  2799.             56 57 58 59 60 61 62 63
  2800.         */
  2801.  
  2802.         /* NOTE: from the schematics, it looks like the top 2 bits should be ignored */
  2803.         /* (there are not output pins for them), and probably taken from the "color" */
  2804.         /* field to do bank switching. However this applies only to TMNT2, with its */
  2805.         /* protection mcu creating the sprite table, so we don't know where to fetch */
  2806.         /* the bits from. */
  2807.         code = READ_WORD(&K053245_ram[offs+0x02]);
  2808.         code = ((code & 0xffe1) + ((code & 0x0010) >> 2) + ((code & 0x0008) << 1)
  2809.                  + ((code & 0x0004) >> 1) + ((code & 0x0002) << 2));
  2810.         color = READ_WORD(&K053245_ram[offs+0x0c]) & 0x00ff;
  2811.         pri = 0;
  2812.  
  2813.         (*K053245_callback)(&code,&color,&pri);
  2814.  
  2815.         size = (READ_WORD(&K053245_ram[offs]) & 0x0f00) >> 8;
  2816.  
  2817.         w = 1 << (size & 0x03);
  2818.         h = 1 << ((size >> 2) & 0x03);
  2819.  
  2820.         /* zoom control:
  2821.            0x40 = normal scale
  2822.           <0x40 enlarge (0x20 = double size)
  2823.           >0x40 reduce (0x80 = half size)
  2824.         */
  2825.         zoomy = READ_WORD(&K053245_ram[offs+0x08]);
  2826.         if (zoomy > 0x2000) continue;
  2827.         if (zoomy) zoomy = (0x400000+zoomy/2) / zoomy;
  2828.         else zoomy = 2 * 0x400000;
  2829.         if ((READ_WORD(&K053245_ram[offs]) & 0x4000) == 0)
  2830.         {
  2831.             zoomx = READ_WORD(&K053245_ram[offs+0x0a]);
  2832.             if (zoomx > 0x2000) continue;
  2833.             if (zoomx) zoomx = (0x400000+zoomx/2) / zoomx;
  2834. //            else zoomx = 2 * 0x400000;
  2835. else zoomx = zoomy; /* workaround for TMNT2 */
  2836.         }
  2837.         else zoomx = zoomy;
  2838.  
  2839.         ox = READ_WORD(&K053245_ram[offs+0x06]) + K053245_spriteoffsX;
  2840.         oy = READ_WORD(&K053245_ram[offs+0x04]);
  2841.  
  2842.         flipx = READ_WORD(&K053245_ram[offs]) & 0x1000;
  2843.         flipy = READ_WORD(&K053245_ram[offs]) & 0x2000;
  2844.         mirrorx = READ_WORD(&K053245_ram[offs+0x0c]) & 0x0100;
  2845.         mirrory = READ_WORD(&K053245_ram[offs+0x0c]) & 0x0200;
  2846.  
  2847.         if (K053245_flipscreenX)
  2848.         {
  2849.             ox = 512 - ox;
  2850.             if (!mirrorx) flipx = !flipx;
  2851.         }
  2852.         if (K053245_flipscreenY)
  2853.         {
  2854.             oy = -oy;
  2855.             if (!mirrory) flipy = !flipy;
  2856.         }
  2857.  
  2858.         ox = (ox + 0x5d) & 0x3ff;
  2859.         if (ox >= 768) ox -= 1024;
  2860.         oy = (-(oy + K053245_spriteoffsY + 0x07)) & 0x3ff;
  2861.         if (oy >= 640) oy -= 1024;
  2862.  
  2863.         /* the coordinates given are for the *center* of the sprite */
  2864.         ox -= (zoomx * w) >> 13;
  2865.         oy -= (zoomy * h) >> 13;
  2866.  
  2867.         for (y = 0;y < h;y++)
  2868.         {
  2869.             int sx,sy,zw,zh;
  2870.  
  2871.             sy = oy + ((zoomy * y + (1<<11)) >> 12);
  2872.             zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
  2873.  
  2874.             for (x = 0;x < w;x++)
  2875.             {
  2876.                 int c,fx,fy;
  2877.  
  2878.                 sx = ox + ((zoomx * x + (1<<11)) >> 12);
  2879.                 zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
  2880.                 c = code;
  2881.                 if (mirrorx)
  2882.                 {
  2883.                     if ((flipx == 0) ^ (2*x < w))
  2884.                     {
  2885.                         /* mirror left/right */
  2886.                         c += (w-x-1);
  2887.                         fx = 1;
  2888.                     }
  2889.                     else
  2890.                     {
  2891.                         c += x;
  2892.                         fx = 0;
  2893.                     }
  2894.                 }
  2895.                 else
  2896.                 {
  2897.                     if (flipx) c += w-1-x;
  2898.                     else c += x;
  2899.                     fx = flipx;
  2900.                 }
  2901.                 if (mirrory)
  2902.                 {
  2903.                     if ((flipy == 0) ^ (2*y >= h))
  2904.                     {
  2905.                         /* mirror top/bottom */
  2906.                         c += 8*(h-y-1);
  2907.                         fy = 1;
  2908.                     }
  2909.                     else
  2910.                     {
  2911.                         c += 8*y;
  2912.                         fy = 0;
  2913.                     }
  2914.                 }
  2915.                 else
  2916.                 {
  2917.                     if (flipy) c += 8*(h-1-y);
  2918.                     else c += 8*y;
  2919.                     fy = flipy;
  2920.                 }
  2921.  
  2922.                 /* the sprite can start at any point in the 8x8 grid, but it must stay */
  2923.                 /* in a 64 entries window, wrapping around at the edges. The animation */
  2924.                 /* at the end of the saloon level in SUnset Riders breaks otherwise. */
  2925.                 c = (c & 0x3f) | (code & ~0x3f);
  2926.  
  2927.                 if (zoomx == 0x10000 && zoomy == 0x10000)
  2928.                 {
  2929.                     /* hack to simulate shadow */
  2930.                     if (READ_WORD(&K053245_ram[offs+0x0c]) & 0x0080)
  2931.                     {
  2932.                         int o = K053245_gfx->colortable[16*color+15];
  2933.                         K053245_gfx->colortable[16*color+15] = palette_transparent_pen;
  2934.                         pdrawgfx(bitmap,K053245_gfx,
  2935.                                 c,
  2936.                                 color,
  2937.                                 fx,fy,
  2938.                                 sx,sy,
  2939.                                 &Machine->drv->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,pri);
  2940.                         K053245_gfx->colortable[16*color+15] = o;
  2941.                     }
  2942.                     else
  2943.                     {
  2944.                         pdrawgfx(bitmap,K053245_gfx,
  2945.                                 c,
  2946.                                 color,
  2947.                                 fx,fy,
  2948.                                 sx,sy,
  2949.                                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0,pri);
  2950.                     }
  2951.                 }
  2952.                 else
  2953.                 {
  2954.                     /* hack to simulate shadow */
  2955.                     if (READ_WORD(&K053245_ram[offs+0x0c]) & 0x0080)
  2956.                     {
  2957.                         int o = K053245_gfx->colortable[16*color+15];
  2958.                         K053245_gfx->colortable[16*color+15] = palette_transparent_pen;
  2959.                         pdrawgfxzoom(bitmap,K053245_gfx,
  2960.                                 c,
  2961.                                 color,
  2962.                                 fx,fy,
  2963.                                 sx,sy,
  2964.                                 &Machine->drv->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,
  2965.                                 (zw << 16) / 16,(zh << 16) / 16,pri);
  2966.                         K053245_gfx->colortable[16*color+15] = o;
  2967.                     }
  2968.                     else
  2969.                     {
  2970.                         pdrawgfxzoom(bitmap,K053245_gfx,
  2971.                                 c,
  2972.                                 color,
  2973.                                 fx,fy,
  2974.                                 sx,sy,
  2975.                                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0,
  2976.                                 (zw << 16) / 16,(zh << 16) / 16,pri);
  2977.                     }
  2978.                 }
  2979.             }
  2980.         }
  2981.     }
  2982. #if 0
  2983. if (keyboard_pressed(KEYCODE_D))
  2984. {
  2985.     FILE *fp;
  2986.     fp=fopen("SPRITE.DMP", "w+b");
  2987.     if (fp)
  2988.     {
  2989.         fwrite(K053245_ram, 0x800, 1, fp);
  2990.         usrintf_showmessage("saved");
  2991.         fclose(fp);
  2992.     }
  2993. }
  2994. #endif
  2995. #undef NUM_SPRITES
  2996. }
  2997.  
  2998. void K053245_mark_sprites_colors(void)
  2999. {
  3000.     int offs,i;
  3001.  
  3002.     unsigned short palette_map[512];
  3003.  
  3004.     memset (palette_map, 0, sizeof (palette_map));
  3005.  
  3006.     /* sprites */
  3007.     for (offs = 0x800-16;offs >= 0;offs -= 16)
  3008.     {
  3009.         if (READ_WORD(&K053245_ram[offs]) & 0x8000)
  3010.         {
  3011.             int code,color,pri;
  3012.  
  3013.             code = READ_WORD(&K053245_ram[offs+0x02]);
  3014.             code = ((code & 0xffe1) + ((code & 0x0010) >> 2) + ((code & 0x0008) << 1)
  3015.                      + ((code & 0x0004) >> 1) + ((code & 0x0002) << 2));
  3016.             color = READ_WORD(&K053245_ram[offs+0x0c]) & 0x00ff;
  3017.             pri = 0;
  3018.             (*K053245_callback)(&code,&color,&pri);
  3019.             palette_map[color] |= 0xffff;
  3020.         }
  3021.     }
  3022.  
  3023.     /* now build the final table */
  3024.     for (i = 0; i < 512; i++)
  3025.     {
  3026.         int usage = palette_map[i], j;
  3027.         if (usage)
  3028.         {
  3029.             for (j = 1; j < 16; j++)
  3030.                 if (usage & (1 << j))
  3031.                     palette_used_colors[i * 16 + j] |= PALETTE_COLOR_VISIBLE;
  3032.         }
  3033.     }
  3034. }
  3035.  
  3036.  
  3037.  
  3038.  
  3039. static int K053247_memory_region;
  3040. static struct GfxElement *K053247_gfx;
  3041. static void (*K053247_callback)(int *code,int *color,int *priority);
  3042. static int K053246_OBJCHA_line;
  3043. static int K053246_romoffset;
  3044. static int K053247_flipscreenX,K053247_flipscreenY;
  3045. static int K053247_spriteoffsX,K053247_spriteoffsY;
  3046. static unsigned char *K053247_ram;
  3047. static int K053247_irq_enabled;
  3048.  
  3049.  
  3050. int K053247_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
  3051.         void (*callback)(int *code,int *color,int *priority))
  3052. {
  3053.     int gfx_index;
  3054.     static struct GfxLayout spritelayout =
  3055.     {
  3056.         16,16,
  3057.         0,                /* filled in later */
  3058.         4,
  3059.         { 0, 0, 0, 0 },    /* filled in later */
  3060.         { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4,
  3061.                 10*4, 11*4, 8*4, 9*4, 14*4, 15*4, 12*4, 13*4 },
  3062.         { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64,
  3063.                 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
  3064.         128*8
  3065.     };
  3066.  
  3067.  
  3068.     /* find first empty slot to decode gfx */
  3069.     for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
  3070.         if (Machine->gfx[gfx_index] == 0)
  3071.             break;
  3072.     if (gfx_index == MAX_GFX_ELEMENTS)
  3073.         return 1;
  3074.  
  3075.     /* tweak the structure for the number of tiles we have */
  3076.     spritelayout.total = memory_region_length(gfx_memory_region) / 128;
  3077.     spritelayout.planeoffset[0] = plane0;
  3078.     spritelayout.planeoffset[1] = plane1;
  3079.     spritelayout.planeoffset[2] = plane2;
  3080.     spritelayout.planeoffset[3] = plane3;
  3081.  
  3082.     /* decode the graphics */
  3083.     Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
  3084.     if (!Machine->gfx[gfx_index])
  3085.         return 1;
  3086.  
  3087.     /* set the color information */
  3088.     Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
  3089.     Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
  3090.  
  3091.     K053247_memory_region = gfx_memory_region;
  3092.     K053247_gfx = Machine->gfx[gfx_index];
  3093.     K053247_callback = callback;
  3094.     K053246_OBJCHA_line = CLEAR_LINE;
  3095.     K053247_ram = malloc(0x1000);
  3096.     if (!K053247_ram) return 1;
  3097.  
  3098.     memset(K053247_ram,0,0x1000);
  3099.  
  3100.     return 0;
  3101. }
  3102.  
  3103. void K053247_vh_stop(void)
  3104. {
  3105.     free(K053247_ram);
  3106.     K053247_ram = 0;
  3107. }
  3108.  
  3109. READ_HANDLER( K053247_word_r )
  3110. {
  3111.     return READ_WORD(&K053247_ram[offset]);
  3112. }
  3113.  
  3114. WRITE_HANDLER( K053247_word_w )
  3115. {
  3116.     COMBINE_WORD_MEM(&K053247_ram[offset],data);
  3117. }
  3118.  
  3119. READ_HANDLER( K053247_r )
  3120. {
  3121.     int shift = ((offset & 1) ^ 1) << 3;
  3122.     return (READ_WORD(&K053247_ram[offset & ~1]) >> shift) & 0xff;
  3123. }
  3124.  
  3125. WRITE_HANDLER( K053247_w )
  3126. {
  3127.     int shift = ((offset & 1) ^ 1) << 3;
  3128.     offset &= ~1;
  3129.     COMBINE_WORD_MEM(&K053247_ram[offset],(0xff000000 >> shift) | ((data & 0xff) << shift));
  3130. }
  3131.  
  3132. READ_HANDLER( K053246_r )
  3133. {
  3134.     if (K053246_OBJCHA_line == ASSERT_LINE)
  3135.     {
  3136.         int addr;
  3137.  
  3138.  
  3139.         addr = 2 * K053246_romoffset + ((offset & 1) ^ 1);
  3140.         addr &= memory_region_length(K053247_memory_region)-1;
  3141.  
  3142. #if 0
  3143.     usrintf_showmessage("%04x: offset %02x addr %06x",cpu_get_pc(),offset,addr);
  3144. #endif
  3145.  
  3146.         return memory_region(K053247_memory_region)[addr];
  3147.     }
  3148.     else
  3149.     {
  3150. logerror("%04x: read from unknown 053244 address %x\n",cpu_get_pc(),offset);
  3151.         return 0;
  3152.     }
  3153. }
  3154.  
  3155. WRITE_HANDLER( K053246_w )
  3156. {
  3157.     if (offset == 0x00)
  3158.         K053247_spriteoffsX = (K053247_spriteoffsX & 0x00ff) | (data << 8);
  3159.     else if (offset == 0x01)
  3160.         K053247_spriteoffsX = (K053247_spriteoffsX & 0xff00) | data;
  3161.     else if (offset == 0x02)
  3162.         K053247_spriteoffsY = (K053247_spriteoffsY & 0x00ff) | (data << 8);
  3163.     else if (offset == 0x03)
  3164.         K053247_spriteoffsY = (K053247_spriteoffsY & 0xff00) | data;
  3165.     else if (offset == 0x05)
  3166.     {
  3167. #ifdef MAME_DEBUG
  3168. if (data & 0xc8)
  3169.     usrintf_showmessage("053246 reg 05 = %02x",data);
  3170. #endif
  3171.         /* bit 0/1 = flip screen */
  3172.         K053247_flipscreenX = data & 0x01;
  3173.         K053247_flipscreenY = data & 0x02;
  3174.  
  3175.         /* bit 2 = unknown */
  3176.  
  3177.         /* bit 4 = interrupt enable */
  3178.         K053247_irq_enabled = data & 0x10;
  3179.  
  3180.         /* bit 5 = unknown */
  3181.  
  3182. logerror("%04x: write %02x to 053246 address 5\n",cpu_get_pc(),data);
  3183.     }
  3184.     else if (offset >= 0x04 && offset < 0x08)   /* only 4,6,7 - 5 is handled above */
  3185.     {
  3186.         offset = 8*(((offset & 0x03) ^ 0x01) - 1);
  3187.         K053246_romoffset = (K053246_romoffset & ~(0xff << offset)) | (data << offset);
  3188.         return;
  3189.     }
  3190.     else
  3191. logerror("%04x: write %02x to unknown 053246 address %x\n",cpu_get_pc(),data,offset);
  3192. }
  3193.  
  3194. READ_HANDLER( K053246_word_r )
  3195. {
  3196.     return K053246_r(offset + 1) | (K053246_r(offset) << 8);
  3197. }
  3198.  
  3199. WRITE_HANDLER( K053246_word_w )
  3200. {
  3201.     if ((data & 0xff000000) == 0)
  3202.         K053246_w(offset,(data >> 8) & 0xff);
  3203.     if ((data & 0x00ff0000) == 0)
  3204.         K053246_w(offset + 1,data & 0xff);
  3205. }
  3206.  
  3207. void K053246_set_OBJCHA_line(int state)
  3208. {
  3209.     K053246_OBJCHA_line = state;
  3210. }
  3211.  
  3212. /*
  3213.  * Sprite Format
  3214.  * ------------------
  3215.  *
  3216.  * Word | Bit(s)           | Use
  3217.  * -----+-fedcba9876543210-+----------------
  3218.  *   0  | x--------------- | active (show this sprite)
  3219.  *   0  | -x-------------- | maintain aspect ratio (when set, zoom y acts on both axis)
  3220.  *   0  | --x------------- | flip y
  3221.  *   0  | ---x------------ | flip x
  3222.  *   0  | ----xxxx-------- | sprite size (see below)
  3223.  *   0  | ---------xxxxxxx | priority order
  3224.  *   1  | xxxxxxxxxxxxxxxx | sprite code
  3225.  *   2  | ------xxxxxxxxxx | y position
  3226.  *   3  | ------xxxxxxxxxx | x position
  3227.  *   4  | xxxxxxxxxxxxxxxx | zoom y (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
  3228.  *   5  | xxxxxxxxxxxxxxxx | zoom x (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
  3229.  *   6  | x--------------- | mirror y (top half is drawn as mirror image of the bottom)
  3230.  *   6  | -x-------------- | mirror x (right half is drawn as mirror image of the left)
  3231.  *   6  | -----x---------- | shadow
  3232.  *   6  | xxxxxxxxxxxxxxxx | "color", but depends on external connections
  3233.  *   7  | ---------------- |
  3234.  *
  3235.  * shadow enables transparent shadows. Note that it applies to pen 0x0f ONLY.
  3236.  * The rest of the sprite remains normal.
  3237.  */
  3238.  
  3239. void K053247_sprites_draw(struct osd_bitmap *bitmap)
  3240. {
  3241. #define NUM_SPRITES 256
  3242.     int offs,pri_code;
  3243.     int sortedlist[NUM_SPRITES];
  3244.  
  3245.     for (offs = 0;offs < NUM_SPRITES;offs++)
  3246.         sortedlist[offs] = -1;
  3247.  
  3248.     /* prebuild a sorted table */
  3249.     for (offs = 0;offs < 0x1000;offs += 16)
  3250.     {
  3251. //        if (READ_WORD(&K053247_ram[offs]) & 0x8000)
  3252.         sortedlist[READ_WORD(&K053247_ram[offs]) & 0x00ff] = offs;
  3253.     }
  3254.  
  3255.     for (pri_code = 0;pri_code < NUM_SPRITES;pri_code++)
  3256.     {
  3257.         int ox,oy,color,code,size,w,h,x,y,xa,ya,flipx,flipy,mirrorx,mirrory,zoomx,zoomy,pri;
  3258.         /* sprites can be grouped up to 8x8. The draw order is
  3259.              0  1  4  5 16 17 20 21
  3260.              2  3  6  7 18 19 22 23
  3261.              8  9 12 13 24 25 28 29
  3262.             10 11 14 15 26 27 30 31
  3263.             32 33 36 37 48 49 52 53
  3264.             34 35 38 39 50 51 54 55
  3265.             40 41 44 45 56 57 60 61
  3266.             42 43 46 47 58 59 62 63
  3267.         */
  3268.         static int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
  3269.         static int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
  3270.         static int offsetkludge;
  3271.  
  3272.  
  3273.         offs = sortedlist[pri_code];
  3274.         if (offs == -1) continue;
  3275.  
  3276.         if ((READ_WORD(&K053247_ram[offs]) & 0x8000) == 0) continue;
  3277.  
  3278.         code = READ_WORD(&K053247_ram[offs+0x02]);
  3279.         color = READ_WORD(&K053247_ram[offs+0x0c]);
  3280.         pri = 0;
  3281.  
  3282.         (*K053247_callback)(&code,&color,&pri);
  3283.  
  3284.         size = (READ_WORD(&K053247_ram[offs]) & 0x0f00) >> 8;
  3285.  
  3286.         w = 1 << (size & 0x03);
  3287.         h = 1 << ((size >> 2) & 0x03);
  3288.  
  3289.         /* the sprite can start at any point in the 8x8 grid. We have to */
  3290.         /* adjust the offsets to draw it correctly. Simpsons does this all the time. */
  3291.         xa = 0;
  3292.         ya = 0;
  3293.         if (code & 0x01) xa += 1;
  3294.         if (code & 0x02) ya += 1;
  3295.         if (code & 0x04) xa += 2;
  3296.         if (code & 0x08) ya += 2;
  3297.         if (code & 0x10) xa += 4;
  3298.         if (code & 0x20) ya += 4;
  3299.         code &= ~0x3f;
  3300.  
  3301.  
  3302.         /* zoom control:
  3303.            0x40 = normal scale
  3304.           <0x40 enlarge (0x20 = double size)
  3305.           >0x40 reduce (0x80 = half size)
  3306.         */
  3307.         zoomy = READ_WORD(&K053247_ram[offs+0x08]);
  3308.         if (zoomy > 0x2000) continue;
  3309.         if (zoomy) zoomy = (0x400000+zoomy/2) / zoomy;
  3310.         else zoomy = 2 * 0x400000;
  3311.         if ((READ_WORD(&K053247_ram[offs]) & 0x4000) == 0)
  3312.         {
  3313.             zoomx = READ_WORD(&K053247_ram[offs+0x0a]);
  3314.             if (zoomx > 0x2000) continue;
  3315.             if (zoomx) zoomx = (0x400000+zoomx/2) / zoomx;
  3316.             else zoomx = 2 * 0x400000;
  3317.         }
  3318.         else zoomx = zoomy;
  3319.  
  3320.         ox = READ_WORD(&K053247_ram[offs+0x06]);
  3321.         oy = READ_WORD(&K053247_ram[offs+0x04]);
  3322.  
  3323. /* TODO: it is not known how the global Y offset works */
  3324. switch (K053247_spriteoffsY)
  3325. {
  3326.     case 0x0261:    /* simpsons */
  3327.     case 0x0262:    /* simpsons (dreamland) */
  3328.     case 0x0263:    /* simpsons (dreamland) */
  3329.     case 0x0264:    /* simpsons (dreamland) */
  3330.     case 0x0265:    /* simpsons (dreamland) */
  3331.     case 0x006d:    /* simpsons flip (dreamland) */
  3332.     case 0x006e:    /* simpsons flip (dreamland) */
  3333.     case 0x006f:    /* simpsons flip (dreamland) */
  3334.     case 0x0070:    /* simpsons flip (dreamland) */
  3335.     case 0x0071:    /* simpsons flip */
  3336.         offsetkludge = 0x017;
  3337.         break;
  3338.     case 0x02f7:    /* vendetta (level 4 boss) */
  3339.     case 0x02f8:    /* vendetta (level 4 boss) */
  3340.     case 0x02f9:    /* vendetta (level 4 boss) */
  3341.     case 0x02fa:    /* vendetta */
  3342.     case 0x02fb:    /* vendetta (fat guy jumping) */
  3343.     case 0x02fc:    /* vendetta (fat guy jumping) */
  3344.     case 0x02fd:    /* vendetta (fat guy jumping) */
  3345.     case 0x02fe:    /* vendetta (fat guy jumping) */
  3346.     case 0x02ff:    /* vendetta (fat guy jumping) */
  3347.     case 0x03f7:    /* vendetta flip (level 4 boss) */
  3348.     case 0x03f8:    /* vendetta flip (level 4 boss) */
  3349.     case 0x03f9:    /* vendetta flip (level 4 boss) */
  3350.     case 0x03fa:    /* vendetta flip */
  3351.     case 0x03fb:    /* vendetta flip (fat guy jumping) */
  3352.     case 0x03fc:    /* vendetta flip (fat guy jumping) */
  3353.     case 0x03fd:    /* vendetta flip (fat guy jumping) */
  3354.     case 0x03fe:    /* vendetta flip (fat guy jumping) */
  3355.     case 0x03ff:    /* vendetta flip (fat guy jumping) */
  3356.         offsetkludge = 0x006;
  3357.         break;
  3358.     case 0x0292:    /* xmen */
  3359.     case 0x0072:    /* xmen flip */
  3360.         offsetkludge = -0x002;
  3361.         break;
  3362.     default:
  3363.         offsetkludge = 0;
  3364.             usrintf_showmessage("unknown spriteoffsY %04x",K053247_spriteoffsY);
  3365.         break;
  3366. }
  3367.  
  3368.         flipx = READ_WORD(&K053247_ram[offs]) & 0x1000;
  3369.         flipy = READ_WORD(&K053247_ram[offs]) & 0x2000;
  3370.         mirrorx = READ_WORD(&K053247_ram[offs+0x0c]) & 0x4000;
  3371.         mirrory = READ_WORD(&K053247_ram[offs+0x0c]) & 0x8000;
  3372.  
  3373.         if (K053247_flipscreenX)
  3374.         {
  3375.             ox = -ox;
  3376.             if (!mirrorx) flipx = !flipx;
  3377.         }
  3378.         if (K053247_flipscreenY)
  3379.         {
  3380.             oy = -oy;
  3381.             if (!mirrory) flipy = !flipy;
  3382.         }
  3383.  
  3384.         ox = (ox + 0x35 - K053247_spriteoffsX) & 0x3ff;
  3385.         if (ox >= 768) ox -= 1024;
  3386.         oy = (-(oy + K053247_spriteoffsY + offsetkludge)) & 0x3ff;
  3387.         if (oy >= 640) oy -= 1024;
  3388.  
  3389.         /* the coordinates given are for the *center* of the sprite */
  3390.         ox -= (zoomx * w) >> 13;
  3391.         oy -= (zoomy * h) >> 13;
  3392.  
  3393.         for (y = 0;y < h;y++)
  3394.         {
  3395.             int sx,sy,zw,zh;
  3396.  
  3397.             sy = oy + ((zoomy * y + (1<<11)) >> 12);
  3398.             zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
  3399.  
  3400.             for (x = 0;x < w;x++)
  3401.             {
  3402.                 int c,fx,fy;
  3403.  
  3404.                 sx = ox + ((zoomx * x + (1<<11)) >> 12);
  3405.                 zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
  3406.                 c = code;
  3407.                 if (mirrorx)
  3408.                 {
  3409.                     if ((flipx == 0) ^ (2*x < w))
  3410.                     {
  3411.                         /* mirror left/right */
  3412.                         c += xoffset[(w-1-x+xa)&7];
  3413.                         fx = 1;
  3414.                     }
  3415.                     else
  3416.                     {
  3417.                         c += xoffset[(x+xa)&7];
  3418.                         fx = 0;
  3419.                     }
  3420.                 }
  3421.                 else
  3422.                 {
  3423.                     if (flipx) c += xoffset[(w-1-x+xa)&7];
  3424.                     else c += xoffset[(x+xa)&7];
  3425.                     fx = flipx;
  3426.                 }
  3427.                 if (mirrory)
  3428.                 {
  3429.                     if ((flipy == 0) ^ (2*y >= h))
  3430.                     {
  3431.                         /* mirror top/bottom */
  3432.                         c += yoffset[(h-1-y+ya)&7];
  3433.                         fy = 1;
  3434.                     }
  3435.                     else
  3436.                     {
  3437.                         c += yoffset[(y+ya)&7];
  3438.                         fy = 0;
  3439.                     }
  3440.                 }
  3441.                 else
  3442.                 {
  3443.                     if (flipy) c += yoffset[(h-1-y+ya)&7];
  3444.                     else c += yoffset[(y+ya)&7];
  3445.                     fy = flipy;
  3446.                 }
  3447.  
  3448.                 if (zoomx == 0x10000 && zoomy == 0x10000)
  3449.                 {
  3450.                     /* hack to simulate shadow */
  3451.                     if (READ_WORD(&K053247_ram[offs+0x0c]) & 0x0400)
  3452.                     {
  3453.                         int o = K053247_gfx->colortable[16*color+15];
  3454.                         K053247_gfx->colortable[16*color+15] = palette_transparent_pen;
  3455.                         pdrawgfx(bitmap,K053247_gfx,
  3456.                                 c,
  3457.                                 color,
  3458.                                 fx,fy,
  3459.                                 sx,sy,
  3460.                                 &Machine->drv->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,pri);
  3461.                         K053247_gfx->colortable[16*color+15] = o;
  3462.                     }
  3463.                     else
  3464.                     {
  3465.                         pdrawgfx(bitmap,K053247_gfx,
  3466.                                 c,
  3467.                                 color,
  3468.                                 fx,fy,
  3469.                                 sx,sy,
  3470.                                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0,pri);
  3471.                     }
  3472.                 }
  3473.                 else
  3474.                 {
  3475.                     /* hack to simulate shadow */
  3476.                     if (READ_WORD(&K053247_ram[offs+0x0c]) & 0x0400)
  3477.                     {
  3478.                         int o = K053247_gfx->colortable[16*color+15];
  3479.                         K053247_gfx->colortable[16*color+15] = palette_transparent_pen;
  3480.                         pdrawgfxzoom(bitmap,K053247_gfx,
  3481.                                 c,
  3482.                                 color,
  3483.                                 fx,fy,
  3484.                                 sx,sy,
  3485.                                 &Machine->drv->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,
  3486.                                 (zw << 16) / 16,(zh << 16) / 16,pri);
  3487.                         K053247_gfx->colortable[16*color+15] = o;
  3488.                     }
  3489.                     else
  3490.                     {
  3491.                         pdrawgfxzoom(bitmap,K053247_gfx,
  3492.                                 c,
  3493.                                 color,
  3494.                                 fx,fy,
  3495.                                 sx,sy,
  3496.                                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0,
  3497.                                 (zw << 16) / 16,(zh << 16) / 16,pri);
  3498.                     }
  3499.                 }
  3500.  
  3501.                 if (mirrory && h == 1)  /* Simpsons shadows */
  3502.                 {
  3503.                     if (zoomx == 0x10000 && zoomy == 0x10000)
  3504.                     {
  3505.                         /* hack to simulate shadow */
  3506.                         if (READ_WORD(&K053247_ram[offs+0x0c]) & 0x0400)
  3507.                         {
  3508.                             int o = K053247_gfx->colortable[16*color+15];
  3509.                             K053247_gfx->colortable[16*color+15] = palette_transparent_pen;
  3510.                             pdrawgfx(bitmap,K053247_gfx,
  3511.                                     c,
  3512.                                     color,
  3513.                                     fx,!fy,
  3514.                                     sx,sy,
  3515.                                     &Machine->drv->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,pri);
  3516.                             K053247_gfx->colortable[16*color+15] = o;
  3517.                         }
  3518.                         else
  3519.                         {
  3520.                             pdrawgfx(bitmap,K053247_gfx,
  3521.                                     c,
  3522.                                     color,
  3523.                                     fx,!fy,
  3524.                                     sx,sy,
  3525.                                     &Machine->drv->visible_area,TRANSPARENCY_PEN,0,pri);
  3526.                         }
  3527.                     }
  3528.                     else
  3529.                     {
  3530.                         /* hack to simulate shadow */
  3531.                         if (READ_WORD(&K053247_ram[offs+0x0c]) & 0x0400)
  3532.                         {
  3533.                             int o = K053247_gfx->colortable[16*color+15];
  3534.                             K053247_gfx->colortable[16*color+15] = palette_transparent_pen;
  3535.                             pdrawgfxzoom(bitmap,K053247_gfx,
  3536.                                     c,
  3537.                                     color,
  3538.                                     fx,!fy,
  3539.                                     sx,sy,
  3540.                                     &Machine->drv->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,
  3541.                                     (zw << 16) / 16,(zh << 16) / 16,pri);
  3542.                             K053247_gfx->colortable[16*color+15] = o;
  3543.                         }
  3544.                         else
  3545.                         {
  3546.                             pdrawgfxzoom(bitmap,K053247_gfx,
  3547.                                     c,
  3548.                                     color,
  3549.                                     fx,!fy,
  3550.                                     sx,sy,
  3551.                                     &Machine->drv->visible_area,TRANSPARENCY_PEN,0,
  3552.                                     (zw << 16) / 16,(zh << 16) / 16,pri);
  3553.                         }
  3554.                     }
  3555.                 }
  3556.             }
  3557.         }
  3558.     }
  3559. #if 0
  3560. if (keyboard_pressed(KEYCODE_D))
  3561. {
  3562.     FILE *fp;
  3563.     fp=fopen("SPRITE.DMP", "w+b");
  3564.     if (fp)
  3565.     {
  3566.         fwrite(K053247_ram, 0x1000, 1, fp);
  3567.         usrintf_showmessage("saved");
  3568.         fclose(fp);
  3569.     }
  3570. }
  3571. #endif
  3572. #undef NUM_SPRITES
  3573. }
  3574.  
  3575. void K053247_mark_sprites_colors(void)
  3576. {
  3577.     int offs,i;
  3578.  
  3579.     unsigned short palette_map[512];
  3580.  
  3581.     memset (palette_map, 0, sizeof (palette_map));
  3582.  
  3583.     /* sprites */
  3584.     for (offs = 0x1000-16;offs >= 0;offs -= 16)
  3585.     {
  3586.         if (READ_WORD(&K053247_ram[offs]) & 0x8000)
  3587.         {
  3588.             int code,color,pri;
  3589.  
  3590.             code = READ_WORD(&K053247_ram[offs+0x02]);
  3591.             color = READ_WORD(&K053247_ram[offs+0x0c]);
  3592.             pri = 0;
  3593.             (*K053247_callback)(&code,&color,&pri);
  3594.             palette_map[color] |= 0xffff;
  3595.         }
  3596.     }
  3597.  
  3598.     /* now build the final table */
  3599.     for (i = 0; i < 512; i++)
  3600.     {
  3601.         int usage = palette_map[i], j;
  3602.         if (usage)
  3603.         {
  3604.             for (j = 1; j < 16; j++)
  3605.                 if (usage & (1 << j))
  3606.                     palette_used_colors[i * 16 + j] |= PALETTE_COLOR_VISIBLE;
  3607.         }
  3608.     }
  3609. }
  3610.  
  3611. int K053247_is_IRQ_enabled(void)
  3612. {
  3613.     return K053247_irq_enabled;
  3614. }
  3615.  
  3616.  
  3617. #define MAX_K051316 3
  3618.  
  3619. static int K051316_memory_region[MAX_K051316];
  3620. static int K051316_gfxnum[MAX_K051316];
  3621. static int K051316_wraparound[MAX_K051316];
  3622. static int K051316_offset[MAX_K051316][2];
  3623. static int K051316_bpp[MAX_K051316];
  3624. static void (*K051316_callback[MAX_K051316])(int *code,int *color);
  3625. static unsigned char *K051316_ram[MAX_K051316];
  3626. static unsigned char K051316_ctrlram[MAX_K051316][16];
  3627. static struct tilemap *K051316_tilemap[MAX_K051316];
  3628. static int K051316_chip_selected;
  3629.  
  3630. void K051316_vh_stop(int chip);
  3631.  
  3632. /***************************************************************************
  3633.  
  3634.   Callbacks for the TileMap code
  3635.  
  3636. ***************************************************************************/
  3637.  
  3638. static void K051316_preupdate(int chip)
  3639. {
  3640.     K051316_chip_selected = chip;
  3641. }
  3642.  
  3643. static void K051316_get_tile_info(int tile_index)
  3644. {
  3645.     int code = K051316_ram[K051316_chip_selected][tile_index];
  3646.     int color = K051316_ram[K051316_chip_selected][tile_index + 0x400];
  3647.  
  3648.     (*K051316_callback[K051316_chip_selected])(&code,&color);
  3649.  
  3650.     SET_TILE_INFO(K051316_gfxnum[K051316_chip_selected],code,color);
  3651. }
  3652.  
  3653.  
  3654. int K051316_vh_start(int chip, int gfx_memory_region,int bpp,
  3655.         void (*callback)(int *code,int *color))
  3656. {
  3657.     int gfx_index;
  3658.  
  3659.  
  3660.     /* find first empty slot to decode gfx */
  3661.     for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
  3662.         if (Machine->gfx[gfx_index] == 0)
  3663.             break;
  3664.     if (gfx_index == MAX_GFX_ELEMENTS)
  3665.         return 1;
  3666.  
  3667.     if (bpp == 4)
  3668.     {
  3669.         static struct GfxLayout charlayout =
  3670.         {
  3671.             16,16,
  3672.             0,                /* filled in later */
  3673.             4,
  3674.             { 0, 1, 2, 3 },
  3675.             { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4,
  3676.                     8*4, 9*4, 10*4, 11*4, 12*4, 13*4, 14*4, 15*4 },
  3677.             { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64,
  3678.                     8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
  3679.             128*8
  3680.         };
  3681.  
  3682.  
  3683.         /* tweak the structure for the number of tiles we have */
  3684.         charlayout.total = memory_region_length(gfx_memory_region) / 128;
  3685.  
  3686.         /* decode the graphics */
  3687.         Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
  3688.     }
  3689.     else if (bpp == 7)
  3690.     {
  3691.         static struct GfxLayout charlayout =
  3692.         {
  3693.             16,16,
  3694.             0,                /* filled in later */
  3695.             7,
  3696.             { 1, 2, 3, 4, 5, 6, 7 },
  3697.             { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,
  3698.                     8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
  3699.             { 0*128, 1*128, 2*128, 3*128, 4*128, 5*128, 6*128, 7*128,
  3700.                     8*128, 9*128, 10*128, 11*128, 12*128, 13*128, 14*128, 15*128 },
  3701.             256*8
  3702.         };
  3703.  
  3704.  
  3705.         /* tweak the structure for the number of tiles we have */
  3706.         charlayout.total = memory_region_length(gfx_memory_region) / 256;
  3707.  
  3708.         /* decode the graphics */
  3709.         Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
  3710.     }
  3711.     else
  3712.     {
  3713. logerror("K051316_vh_start supports only 4 or 7 bpp\n");
  3714.         return 1;
  3715.     }
  3716.  
  3717.     if (!Machine->gfx[gfx_index])
  3718.         return 1;
  3719.  
  3720.     /* set the color information */
  3721.     Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
  3722.     Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / (1 << bpp);
  3723.  
  3724.     K051316_memory_region[chip] = gfx_memory_region;
  3725.     K051316_gfxnum[chip] = gfx_index;
  3726.     K051316_bpp[chip] = bpp;
  3727.     K051316_callback[chip] = callback;
  3728.  
  3729.     K051316_tilemap[chip] = tilemap_create(K051316_get_tile_info,tilemap_scan_rows,TILEMAP_OPAQUE,16,16,32,32);
  3730.  
  3731.     K051316_ram[chip] = malloc(0x800);
  3732.  
  3733.     if (!K051316_ram[chip] || !K051316_tilemap[chip])
  3734.     {
  3735.         K051316_vh_stop(chip);
  3736.         return 1;
  3737.     }
  3738.  
  3739.     tilemap_set_clip(K051316_tilemap[chip],0);
  3740.  
  3741.     K051316_wraparound[chip] = 0;    /* default = no wraparound */
  3742.     K051316_offset[chip][0] = K051316_offset[chip][1] = 0;
  3743.  
  3744.     return 0;
  3745. }
  3746.  
  3747. int K051316_vh_start_0(int gfx_memory_region,int bpp,
  3748.         void (*callback)(int *code,int *color))
  3749. {
  3750.     return K051316_vh_start(0,gfx_memory_region,bpp,callback);
  3751. }
  3752.  
  3753. int K051316_vh_start_1(int gfx_memory_region,int bpp,
  3754.         void (*callback)(int *code,int *color))
  3755. {
  3756.     return K051316_vh_start(1,gfx_memory_region,bpp,callback);
  3757. }
  3758.  
  3759. int K051316_vh_start_2(int gfx_memory_region,int bpp,
  3760.         void (*callback)(int *code,int *color))
  3761. {
  3762.     return K051316_vh_start(2,gfx_memory_region,bpp,callback);
  3763. }
  3764.  
  3765.  
  3766. void K051316_vh_stop(int chip)
  3767. {
  3768.     free(K051316_ram[chip]);
  3769. }
  3770.  
  3771. void K051316_vh_stop_0(void)
  3772. {
  3773.     K051316_vh_stop(0);
  3774. }
  3775.  
  3776. void K051316_vh_stop_1(void)
  3777. {
  3778.     K051316_vh_stop(1);
  3779. }
  3780.  
  3781. void K051316_vh_stop_2(void)
  3782. {
  3783.     K051316_vh_stop(2);
  3784. }
  3785.  
  3786. int K051316_r(int chip, int offset)
  3787. {
  3788.     return K051316_ram[chip][offset];
  3789. }
  3790.  
  3791. READ_HANDLER( K051316_0_r )
  3792. {
  3793.     return K051316_r(0, offset);
  3794. }
  3795.  
  3796. READ_HANDLER( K051316_1_r )
  3797. {
  3798.     return K051316_r(1, offset);
  3799. }
  3800.  
  3801. READ_HANDLER( K051316_2_r )
  3802. {
  3803.     return K051316_r(2, offset);
  3804. }
  3805.  
  3806.  
  3807. void K051316_w(int chip,int offset,int data)
  3808. {
  3809.     if (K051316_ram[chip][offset] != data)
  3810.     {
  3811.         K051316_ram[chip][offset] = data;
  3812.         tilemap_mark_tile_dirty(K051316_tilemap[chip],offset & 0x3ff);
  3813.     }
  3814. }
  3815.  
  3816. WRITE_HANDLER( K051316_0_w )
  3817. {
  3818.     K051316_w(0,offset,data);
  3819. }
  3820.  
  3821. WRITE_HANDLER( K051316_1_w )
  3822. {
  3823.     K051316_w(1,offset,data);
  3824. }
  3825.  
  3826. WRITE_HANDLER( K051316_2_w )
  3827. {
  3828.     K051316_w(2,offset,data);
  3829. }
  3830.  
  3831.  
  3832. int K051316_rom_r(int chip, int offset)
  3833. {
  3834.     if ((K051316_ctrlram[chip][0x0e] & 0x01) == 0)
  3835.     {
  3836.         int addr;
  3837.  
  3838.         addr = offset + (K051316_ctrlram[chip][0x0c] << 11) + (K051316_ctrlram[chip][0x0d] << 19);
  3839.         if (K051316_bpp[chip] <= 4) addr /= 2;
  3840.         addr &= memory_region_length(K051316_memory_region[chip])-1;
  3841.  
  3842. #if 0
  3843.     usrintf_showmessage("%04x: offset %04x addr %04x",cpu_get_pc(),offset,addr);
  3844. #endif
  3845.  
  3846.         return memory_region(K051316_memory_region[chip])[addr];
  3847.     }
  3848.     else
  3849.     {
  3850. logerror("%04x: read 051316 ROM offset %04x but reg 0x0c bit 0 not clear\n",cpu_get_pc(),offset);
  3851.         return 0;
  3852.     }
  3853. }
  3854.  
  3855. READ_HANDLER( K051316_rom_0_r )
  3856. {
  3857.     return K051316_rom_r(0,offset);
  3858. }
  3859.  
  3860. READ_HANDLER( K051316_rom_1_r )
  3861. {
  3862.     return K051316_rom_r(1,offset);
  3863. }
  3864.  
  3865. READ_HANDLER( K051316_rom_2_r )
  3866. {
  3867.     return K051316_rom_r(2,offset);
  3868. }
  3869.  
  3870.  
  3871.  
  3872. void K051316_ctrl_w(int chip,int offset,int data)
  3873. {
  3874.     K051316_ctrlram[chip][offset] = data;
  3875. if (offset >= 0x0c) logerror("%04x: write %02x to 051316 reg %x\n",cpu_get_pc(),data,offset);
  3876. }
  3877.  
  3878. WRITE_HANDLER( K051316_ctrl_0_w )
  3879. {
  3880.     K051316_ctrl_w(0,offset,data);
  3881. }
  3882.  
  3883. WRITE_HANDLER( K051316_ctrl_1_w )
  3884. {
  3885.     K051316_ctrl_w(1,offset,data);
  3886. }
  3887.  
  3888. WRITE_HANDLER( K051316_ctrl_2_w )
  3889. {
  3890.     K051316_ctrl_w(2,offset,data);
  3891. }
  3892.  
  3893. void K051316_wraparound_enable(int chip, int status)
  3894. {
  3895.     K051316_wraparound[chip] = status;
  3896. }
  3897.  
  3898. void K051316_set_offset(int chip, int xoffs, int yoffs)
  3899. {
  3900.     K051316_offset[chip][0] = xoffs;
  3901.     K051316_offset[chip][1] = yoffs;
  3902. }
  3903.  
  3904. void K051316_tilemap_update(int chip)
  3905. {
  3906.     K051316_preupdate(chip);
  3907.     tilemap_update(K051316_tilemap[chip]);
  3908. }
  3909.  
  3910. void K051316_tilemap_update_0(void)
  3911. {
  3912.     K051316_tilemap_update(0);
  3913. }
  3914.  
  3915. void K051316_tilemap_update_1(void)
  3916. {
  3917.     K051316_tilemap_update(1);
  3918. }
  3919.  
  3920. void K051316_tilemap_update_2(void)
  3921. {
  3922.     K051316_tilemap_update(2);
  3923. }
  3924.  
  3925.  
  3926. /* Note: rotation support doesn't handle asymmetrical visible areas. This doesn't */
  3927. /* matter because in the Konami games the visible area is always symmetrical. */
  3928. void K051316_zoom_draw(int chip, struct osd_bitmap *bitmap,UINT32 priority)
  3929. {
  3930.     UINT32 startx,starty,cx,cy;
  3931.     int incxx,incxy,incyx,incyy;
  3932.     int x,sx,sy,ex,ey;
  3933.     struct osd_bitmap *srcbitmap = K051316_tilemap[chip]->pixmap;
  3934.  
  3935.     startx = 256 * ((INT16)(256 * K051316_ctrlram[chip][0x00] + K051316_ctrlram[chip][0x01]));
  3936.     incxx  =        (INT16)(256 * K051316_ctrlram[chip][0x02] + K051316_ctrlram[chip][0x03]);
  3937.     incyx  =        (INT16)(256 * K051316_ctrlram[chip][0x04] + K051316_ctrlram[chip][0x05]);
  3938.     starty = 256 * ((INT16)(256 * K051316_ctrlram[chip][0x06] + K051316_ctrlram[chip][0x07]));
  3939.     incxy  =        (INT16)(256 * K051316_ctrlram[chip][0x08] + K051316_ctrlram[chip][0x09]);
  3940.     incyy  =        (INT16)(256 * K051316_ctrlram[chip][0x0a] + K051316_ctrlram[chip][0x0b]);
  3941.  
  3942.     startx += (Machine->drv->visible_area.min_y - (16 + K051316_offset[chip][1])) * incyx;
  3943.     starty += (Machine->drv->visible_area.min_y - (16 + K051316_offset[chip][1])) * incyy;
  3944.  
  3945.     startx += (Machine->drv->visible_area.min_x - (89 + K051316_offset[chip][0])) * incxx;
  3946.     starty += (Machine->drv->visible_area.min_x - (89 + K051316_offset[chip][0])) * incxy;
  3947.  
  3948.     sx = Machine->drv->visible_area.min_x;
  3949.     sy = Machine->drv->visible_area.min_y;
  3950.     ex = Machine->drv->visible_area.max_x;
  3951.     ey = Machine->drv->visible_area.max_y;
  3952.  
  3953.     if (Machine->orientation & ORIENTATION_SWAP_XY)
  3954.     {
  3955.         int t;
  3956.  
  3957.         t = startx; startx = starty; starty = t;
  3958.         t = sx; sx = sy; sy = t;
  3959.         t = ex; ex = ey; ey = t;
  3960.         t = incxx; incxx = incyy; incyy = t;
  3961.         t = incxy; incxy = incyx; incyx = t;
  3962.     }
  3963.  
  3964.     if (Machine->orientation & ORIENTATION_FLIP_X)
  3965.     {
  3966.         int w = ex - sx;
  3967.  
  3968.         incxy = -incxy;
  3969.         incyx = -incyx;
  3970.         startx = 0xfffff - startx;
  3971.         startx -= incxx * w;
  3972.         starty -= incxy * w;
  3973.     }
  3974.  
  3975.     if (Machine->orientation & ORIENTATION_FLIP_Y)
  3976.     {
  3977.         int h = ey - sy;
  3978.  
  3979.         incxy = -incxy;
  3980.         incyx = -incyx;
  3981.         starty = 0xfffff - starty;
  3982.         startx -= incyx * h;
  3983.         starty -= incyy * h;
  3984.     }
  3985.  
  3986.     if (bitmap->depth == 8)
  3987.     {
  3988.         UINT8 *dest;
  3989.  
  3990.         if (incxy == 0 && incyx == 0 && !K051316_wraparound[chip])
  3991.         {
  3992.             /* optimized loop for the not rotated case */
  3993.  
  3994.             if (incxx == 0x800)
  3995.             {
  3996.                 /* optimized loop for the not zoomed case */
  3997.  
  3998.                 /* startx is unsigned */
  3999.                 startx = ((INT32)startx) >> 11;
  4000.  
  4001.                 if (startx >= 512)
  4002.                 {
  4003.                     sx += -startx;
  4004.                     startx = 0;
  4005.                 }
  4006.  
  4007.                 if (sx <= ex)
  4008.                 {
  4009.                     while (sy <= ey)
  4010.                     {
  4011.                         if ((starty & 0xfff00000) == 0)
  4012.                         {
  4013.                             x = sx;
  4014.                             cx = startx;
  4015.                             cy = starty >> 11;
  4016.                             dest = &bitmap->line[sy][sx];
  4017.                             if (priority)
  4018.                             {
  4019.                                 UINT8 *pri = &priority_bitmap->line[sy][sx];
  4020.  
  4021.                                 while (x <= ex && cx < 512)
  4022.                                 {
  4023.                                     int c = srcbitmap->line[cy][cx];
  4024.  
  4025.                                     if (c != palette_transparent_pen)
  4026.                                     {
  4027.                                         *dest = c;
  4028.                                         *pri |= priority;
  4029.                                     }
  4030.  
  4031.                                     cx++;
  4032.                                     x++;
  4033.                                     dest++;
  4034.                                     pri++;
  4035.                                 }
  4036.                             }
  4037.                             else
  4038.                             {
  4039.                                 while (x <= ex && cx < 512)
  4040.                                 {
  4041.                                     int c = srcbitmap->line[cy][cx];
  4042.  
  4043.                                     if (c != palette_transparent_pen)
  4044.                                         *dest = c;
  4045.  
  4046.                                     cx++;
  4047.                                     x++;
  4048.                                     dest++;
  4049.                                 }
  4050.                             }
  4051.                         }
  4052.                         starty += incyy;
  4053.                         sy++;
  4054.                     }
  4055.                 }
  4056.             }
  4057.             else
  4058.             {
  4059.                 while ((startx & 0xfff00000) != 0 && sx <= ex)
  4060.                 {
  4061.                     startx += incxx;
  4062.                     sx++;
  4063.                 }
  4064.  
  4065.                 if ((startx & 0xfff00000) == 0)
  4066.                 {
  4067.                     while (sy <= ey)
  4068.                     {
  4069.                         if ((starty & 0xfff00000) == 0)
  4070.                         {
  4071.                             x = sx;
  4072.                             cx = startx;
  4073.                             cy = starty >> 11;
  4074.                             dest = &bitmap->line[sy][sx];
  4075.                             if (priority)
  4076.                             {
  4077.                                 UINT8 *pri = &priority_bitmap->line[sy][sx];
  4078.  
  4079.                                 while (x <= ex && (cx & 0xfff00000) == 0)
  4080.                                 {
  4081.                                     int c = srcbitmap->line[cy][cx >> 11];
  4082.  
  4083.                                     if (c != palette_transparent_pen)
  4084.                                     {
  4085.                                         *dest = c;
  4086.                                         *pri |= priority;
  4087.                                     }
  4088.  
  4089.                                     cx += incxx;
  4090.                                     x++;
  4091.                                     dest++;
  4092.                                     pri++;
  4093.                                 }
  4094.                             }
  4095.                             else
  4096.                             {
  4097.                                 while (x <= ex && (cx & 0xfff00000) == 0)
  4098.                                 {
  4099.                                     int c = srcbitmap->line[cy][cx >> 11];
  4100.  
  4101.                                     if (c != palette_transparent_pen)
  4102.                                         *dest = c;
  4103.  
  4104.                                     cx += incxx;
  4105.                                     x++;
  4106.                                     dest++;
  4107.                                 }
  4108.                             }
  4109.                         }
  4110.                         starty += incyy;
  4111.                         sy++;
  4112.                     }
  4113.                 }
  4114.             }
  4115.         }
  4116.         else
  4117.         {
  4118.             if (K051316_wraparound[chip])
  4119.             {
  4120.                 /* plot with wraparound */
  4121.                 while (sy <= ey)
  4122.                 {
  4123.                     x = sx;
  4124.                     cx = startx;
  4125.                     cy = starty;
  4126.                     dest = &bitmap->line[sy][sx];
  4127.                     if (priority)
  4128.                     {
  4129.                         UINT8 *pri = &priority_bitmap->line[sy][sx];
  4130.  
  4131.                         while (x <= ex)
  4132.                         {
  4133.                             int c = srcbitmap->line[(cy >> 11) & 0x1ff][(cx >> 11) & 0x1ff];
  4134.  
  4135.                             if (c != palette_transparent_pen)
  4136.                             {
  4137.                                 *dest = c;
  4138.                                 *pri |= priority;
  4139.                             }
  4140.  
  4141.                             cx += incxx;
  4142.                             cy += incxy;
  4143.                             x++;
  4144.                             dest++;
  4145.                             pri++;
  4146.                         }
  4147.                     }
  4148.                     else
  4149.                     {
  4150.                         while (x <= ex)
  4151.                         {
  4152.                             int c = srcbitmap->line[(cy >> 11) & 0x1ff][(cx >> 11) & 0x1ff];
  4153.  
  4154.                             if (c != palette_transparent_pen)
  4155.                                 *dest = c;
  4156.  
  4157.                             cx += incxx;
  4158.                             cy += incxy;
  4159.                             x++;
  4160.                             dest++;
  4161.                         }
  4162.                     }
  4163.                     startx += incyx;
  4164.                     starty += incyy;
  4165.                     sy++;
  4166.                 }
  4167.             }
  4168.             else
  4169.             {
  4170.                 while (sy <= ey)
  4171.                 {
  4172.                     x = sx;
  4173.                     cx = startx;
  4174.                     cy = starty;
  4175.                     dest = &bitmap->line[sy][sx];
  4176.                     if (priority)
  4177.                     {
  4178.                         UINT8 *pri = &priority_bitmap->line[sy][sx];
  4179.  
  4180.                         while (x <= ex)
  4181.                         {
  4182.                             if ((cx & 0xfff00000) == 0 && (cy & 0xfff00000) == 0)
  4183.                             {
  4184.                                 int c = srcbitmap->line[cy >> 11][cx >> 11];
  4185.  
  4186.                                 if (c != palette_transparent_pen)
  4187.                                 {
  4188.                                     *dest = c;
  4189.                                     *pri |= priority;
  4190.                                 }
  4191.                             }
  4192.  
  4193.                             cx += incxx;
  4194.                             cy += incxy;
  4195.                             x++;
  4196.                             dest++;
  4197.                             pri++;
  4198.                         }
  4199.                     }
  4200.                     else
  4201.                     {
  4202.                         while (x <= ex)
  4203.                         {
  4204.                             if ((cx & 0xfff00000) == 0 && (cy & 0xfff00000) == 0)
  4205.                             {
  4206.                                 int c = srcbitmap->line[cy >> 11][cx >> 11];
  4207.  
  4208.                                 if (c != palette_transparent_pen)
  4209.                                     *dest = c;
  4210.                             }
  4211.  
  4212.                             cx += incxx;
  4213.                             cy += incxy;
  4214.                             x++;
  4215.                             dest++;
  4216.                         }
  4217.                     }
  4218.                     startx += incyx;
  4219.                     starty += incyy;
  4220.                     sy++;
  4221.                 }
  4222.             }
  4223.         }
  4224.     }
  4225.     else
  4226.     {
  4227.         /* 16-bit case */
  4228.         UINT16 *dest;
  4229.  
  4230.         if (incxy == 0 && incyx == 0 && !K051316_wraparound[chip])
  4231.         {
  4232.             /* optimized loop for the not rotated case */
  4233.  
  4234.             if (incxx == 0x800)
  4235.             {
  4236.                 /* optimized loop for the not zoomed case */
  4237.  
  4238.                 /* startx is unsigned */
  4239.                 startx = ((INT32)startx) >> 11;
  4240.  
  4241.                 if (startx >= 512)
  4242.                 {
  4243.                     sx += -startx;
  4244.                     startx = 0;
  4245.                 }
  4246.  
  4247.                 if (sx <= ex)
  4248.                 {
  4249.                     while (sy <= ey)
  4250.                     {
  4251.                         if ((starty & 0xfff00000) == 0)
  4252.                         {
  4253.                             x = sx;
  4254.                             cx = startx;
  4255.                             cy = starty >> 11;
  4256.                             dest = &((unsigned short *)bitmap->line[sy])[sx];
  4257.                             while (x <= ex && cx < 512)
  4258.                             {
  4259.                                 int c = ((unsigned short *)srcbitmap->line[cy])[cx];
  4260.  
  4261.                                 if (c != palette_transparent_pen)
  4262.                                     *dest = c;
  4263.  
  4264.                                 cx++;
  4265.                                 x++;
  4266.                                 dest++;
  4267.                             }
  4268.                         }
  4269.                         starty += incyy;
  4270.                         sy++;
  4271.                     }
  4272.                 }
  4273.             }
  4274.             else
  4275.             {
  4276.                 while ((startx & 0xfff00000) != 0 && sx <= ex)
  4277.                 {
  4278.                     startx += incxx;
  4279.                     sx++;
  4280.                 }
  4281.  
  4282.                 if ((startx & 0xfff00000) == 0)
  4283.                 {
  4284.                     while (sy <= ey)
  4285.                     {
  4286.                         if ((starty & 0xfff00000) == 0)
  4287.                         {
  4288.                             x = sx;
  4289.                             cx = startx;
  4290.                             cy = starty >> 11;
  4291.                             dest = &((unsigned short *)bitmap->line[sy])[sx];
  4292.                             while (x <= ex && (cx & 0xfff00000) == 0)
  4293.                             {
  4294.                                 int c = ((unsigned short *)srcbitmap->line[cy])[cx >> 11];
  4295.  
  4296.                                 if (c != palette_transparent_pen)
  4297.                                     *dest = c;
  4298.  
  4299.                                 cx += incxx;
  4300.                                 x++;
  4301.                                 dest++;
  4302.                             }
  4303.                         }
  4304.                         starty += incyy;
  4305.                         sy++;
  4306.                     }
  4307.                 }
  4308.             }
  4309.         }
  4310.         else
  4311.         {
  4312.             if (K051316_wraparound[chip])
  4313.             {
  4314.                 /* plot with wraparound */
  4315.                 while (sy <= ey)
  4316.                 {
  4317.                     x = sx;
  4318.                     cx = startx;
  4319.                     cy = starty;
  4320.                     dest = &((unsigned short *)bitmap->line[sy])[sx];
  4321.                     while (x <= ex)
  4322.                     {
  4323.                         int c = ((unsigned short *)srcbitmap->line[(cy >> 11) & 0x1ff])[(cx >> 11) & 0x1ff];
  4324.  
  4325.                         if (c != palette_transparent_pen)
  4326.                             *dest = c;
  4327.  
  4328.                         cx += incxx;
  4329.                         cy += incxy;
  4330.                         x++;
  4331.                         dest++;
  4332.                     }
  4333.                     startx += incyx;
  4334.                     starty += incyy;
  4335.                     sy++;
  4336.                 }
  4337.             }
  4338.             else
  4339.             {
  4340.                 while (sy <= ey)
  4341.                 {
  4342.                     x = sx;
  4343.                     cx = startx;
  4344.                     cy = starty;
  4345.                     dest = &((unsigned short *)bitmap->line[sy])[sx];
  4346.                     while (x <= ex)
  4347.                     {
  4348.                         if ((cx & 0xfff00000) == 0 && (cy & 0xfff00000) == 0)
  4349.                         {
  4350.                             int c = ((unsigned short *)srcbitmap->line[cy >> 11])[cx >> 11];
  4351.  
  4352.                             if (c != palette_transparent_pen)
  4353.                                 *dest = c;
  4354.                         }
  4355.  
  4356.                         cx += incxx;
  4357.                         cy += incxy;
  4358.                         x++;
  4359.                         dest++;
  4360.                     }
  4361.                     startx += incyx;
  4362.                     starty += incyy;
  4363.                     sy++;
  4364.                 }
  4365.             }
  4366.         }
  4367.     }
  4368. #if 0
  4369.     usrintf_showmessage("%02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x",
  4370.             K051316_ctrlram[chip][0x00],
  4371.             K051316_ctrlram[chip][0x01],
  4372.             K051316_ctrlram[chip][0x02],
  4373.             K051316_ctrlram[chip][0x03],
  4374.             K051316_ctrlram[chip][0x04],
  4375.             K051316_ctrlram[chip][0x05],
  4376.             K051316_ctrlram[chip][0x06],
  4377.             K051316_ctrlram[chip][0x07],
  4378.             K051316_ctrlram[chip][0x08],
  4379.             K051316_ctrlram[chip][0x09],
  4380.             K051316_ctrlram[chip][0x0a],
  4381.             K051316_ctrlram[chip][0x0b],
  4382.             K051316_ctrlram[chip][0x0c],    /* bank for ROM testing */
  4383.             K051316_ctrlram[chip][0x0d],
  4384.             K051316_ctrlram[chip][0x0e],    /* 0 = test ROMs */
  4385.             K051316_ctrlram[chip][0x0f]);
  4386. #endif
  4387. }
  4388.  
  4389. void K051316_zoom_draw_0(struct osd_bitmap *bitmap,UINT32 priority)
  4390. {
  4391.     K051316_zoom_draw(0,bitmap,priority);
  4392. }
  4393.  
  4394. void K051316_zoom_draw_1(struct osd_bitmap *bitmap,UINT32 priority)
  4395. {
  4396.     K051316_zoom_draw(1,bitmap,priority);
  4397. }
  4398.  
  4399. void K051316_zoom_draw_2(struct osd_bitmap *bitmap,UINT32 priority)
  4400. {
  4401.     K051316_zoom_draw(2,bitmap,priority);
  4402. }
  4403.  
  4404.  
  4405.  
  4406.  
  4407. static unsigned char K053251_ram[16];
  4408. static int K053251_palette_index[5];
  4409.  
  4410. WRITE_HANDLER( K053251_w )
  4411. {
  4412.     data &= 0x3f;
  4413.  
  4414.     if (K053251_ram[offset] != data)
  4415.     {
  4416.         K053251_ram[offset] = data;
  4417.         if (offset == 9)
  4418.         {
  4419.             /* palette base index */
  4420.             K053251_palette_index[0] = 32 * ((data >> 0) & 0x03);
  4421.             K053251_palette_index[1] = 32 * ((data >> 2) & 0x03);
  4422.             K053251_palette_index[2] = 32 * ((data >> 4) & 0x03);
  4423.             tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
  4424.         }
  4425.         else if (offset == 10)
  4426.         {
  4427.             /* palette base index */
  4428.             K053251_palette_index[3] = 16 * ((data >> 0) & 0x07);
  4429.             K053251_palette_index[4] = 16 * ((data >> 3) & 0x07);
  4430.             tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
  4431.         }
  4432. #if 0
  4433. else
  4434. {
  4435. logerror("%04x: write %02x to K053251 register %04x\n",cpu_get_pc(),data&0xff,offset);
  4436. usrintf_showmessage("pri = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x",
  4437.     K053251_ram[0],K053251_ram[1],K053251_ram[2],K053251_ram[3],
  4438.     K053251_ram[4],K053251_ram[5],K053251_ram[6],K053251_ram[7],
  4439.     K053251_ram[8],K053251_ram[9],K053251_ram[10],K053251_ram[11],
  4440.     K053251_ram[12],K053251_ram[13],K053251_ram[14],K053251_ram[15]
  4441.     );
  4442. }
  4443. #endif
  4444.     }
  4445. }
  4446.  
  4447. int K053251_get_priority(int ci)
  4448. {
  4449.     return K053251_ram[ci];
  4450. }
  4451.  
  4452. int K053251_get_palette_index(int ci)
  4453. {
  4454.     return K053251_palette_index[ci];
  4455. }
  4456.  
  4457.  
  4458.  
  4459. static unsigned char K054000_ram[0x20];
  4460.  
  4461. static WRITE_HANDLER( collision_w )
  4462. {
  4463. }
  4464.  
  4465. WRITE_HANDLER( K054000_w )
  4466. {
  4467. #if VERBOSE
  4468. logerror("%04x: write %02x to 054000 address %02x\n",cpu_get_pc(),data,offset);
  4469. #endif
  4470.  
  4471.     K054000_ram[offset] = data;
  4472. }
  4473.  
  4474. READ_HANDLER( K054000_r )
  4475. {
  4476.     int Acx,Acy,Aax,Aay;
  4477.     int Bcx,Bcy,Bax,Bay;
  4478.  
  4479.  
  4480. #if VERBOSE
  4481. logerror("%04x: read 054000 address %02x\n",cpu_get_pc(),offset);
  4482. #endif
  4483.  
  4484.     if (offset != 0x18) return 0;
  4485.  
  4486.  
  4487.     Acx = (K054000_ram[0x01] << 16) | (K054000_ram[0x02] << 8) | K054000_ram[0x03];
  4488.     Acy = (K054000_ram[0x09] << 16) | (K054000_ram[0x0a] << 8) | K054000_ram[0x0b];
  4489. /* TODO: this is a hack to make thndrx2 pass the startup check. It is certainly wrong. */
  4490. if (K054000_ram[0x04] == 0xff) Acx+=3;
  4491. if (K054000_ram[0x0c] == 0xff) Acy+=3;
  4492.     Aax = K054000_ram[0x06] + 1;
  4493.     Aay = K054000_ram[0x07] + 1;
  4494.  
  4495.     Bcx = (K054000_ram[0x15] << 16) | (K054000_ram[0x16] << 8) | K054000_ram[0x17];
  4496.     Bcy = (K054000_ram[0x11] << 16) | (K054000_ram[0x12] << 8) | K054000_ram[0x13];
  4497.     Bax = K054000_ram[0x0e] + 1;
  4498.     Bay = K054000_ram[0x0f] + 1;
  4499.  
  4500.     if (Acx + Aax < Bcx - Bax)
  4501.         return 1;
  4502.  
  4503.     if (Bcx + Bax < Acx - Aax)
  4504.         return 1;
  4505.  
  4506.     if (Acy + Aay < Bcy - Bay)
  4507.         return 1;
  4508.  
  4509.     if (Bcy + Bay < Acy - Aay)
  4510.         return 1;
  4511.  
  4512.     return 0;
  4513. }
  4514.  
  4515. static unsigned char K051733_ram[0x20];
  4516.  
  4517. WRITE_HANDLER( K051733_w )
  4518. {
  4519. #if VERBOSE
  4520. logerror("%04x: write %02x to 051733 address %02x\n",cpu_get_pc(),data,offset);
  4521. #endif
  4522.  
  4523.     K051733_ram[offset] = data;
  4524. }
  4525.  
  4526. READ_HANDLER( K051733_r )
  4527. {
  4528.     int op1 = (K051733_ram[0x00] << 8) | K051733_ram[0x01];
  4529.     int op2 = (K051733_ram[0x02] << 8) | K051733_ram[0x03];
  4530.  
  4531.     int rad = (K051733_ram[0x06] << 8) | K051733_ram[0x07];
  4532.     int yobj1c = (K051733_ram[0x08] << 8) | K051733_ram[0x09];
  4533.     int xobj1c = (K051733_ram[0x0a] << 8) | K051733_ram[0x0b];
  4534.     int yobj2c = (K051733_ram[0x0c] << 8) | K051733_ram[0x0d];
  4535.     int xobj2c = (K051733_ram[0x0e] << 8) | K051733_ram[0x0f];
  4536.  
  4537. #if VERBOSE
  4538. logerror("%04x: read 051733 address %02x\n",cpu_get_pc(),offset);
  4539. #endif
  4540.  
  4541.     switch(offset){
  4542.         case 0x00:
  4543.             if (op2) return    ((op1/op2) >> 8);
  4544.             else return 0xff;
  4545.         case 0x01:
  4546.             if (op2) return    op1/op2;
  4547.             else return 0xff;
  4548.  
  4549.         /* this is completely unverified */
  4550.         case 0x02:
  4551.             if (op2) return    ((op1%op2) >> 8);
  4552.             else return 0xff;
  4553.         case 0x03:
  4554.             if (op2) return    op1%op2;
  4555.             else return 0xff;
  4556.  
  4557.         case 0x07:{
  4558.             if (xobj1c + rad < xobj2c - rad)
  4559.                 return 0x80;
  4560.  
  4561.             if (xobj2c + rad < xobj1c - rad)
  4562.                 return 0x80;
  4563.  
  4564.             if (yobj1c + rad < yobj2c - rad)
  4565.                 return 0x80;
  4566.  
  4567.             if (yobj2c + rad < yobj1c - rad)
  4568.                 return 0x80;
  4569.  
  4570.             return 0;
  4571.         }
  4572.         default:
  4573.             return K051733_ram[offset];
  4574.     }
  4575. }
  4576.